1//===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file implements semantic analysis for OpenMP directives and
10/// clauses.
11///
12//===----------------------------------------------------------------------===//
13
14#include "TreeTransform.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/ASTMutationListener.h"
17#include "clang/AST/CXXInheritance.h"
18#include "clang/AST/Decl.h"
19#include "clang/AST/DeclCXX.h"
20#include "clang/AST/DeclOpenMP.h"
21#include "clang/AST/OpenMPClause.h"
22#include "clang/AST/StmtCXX.h"
23#include "clang/AST/StmtOpenMP.h"
24#include "clang/AST/StmtVisitor.h"
25#include "clang/AST/TypeOrdering.h"
26#include "clang/Basic/DiagnosticSema.h"
27#include "clang/Basic/OpenMPKinds.h"
28#include "clang/Basic/PartialDiagnostic.h"
29#include "clang/Basic/TargetInfo.h"
30#include "clang/Sema/Initialization.h"
31#include "clang/Sema/Lookup.h"
32#include "clang/Sema/Scope.h"
33#include "clang/Sema/ScopeInfo.h"
34#include "clang/Sema/SemaInternal.h"
35#include "llvm/ADT/IndexedMap.h"
36#include "llvm/ADT/PointerEmbeddedInt.h"
37#include "llvm/ADT/STLExtras.h"
38#include "llvm/ADT/StringExtras.h"
39#include "llvm/Frontend/OpenMP/OMPConstants.h"
40#include <set>
41
42using namespace clang;
43using namespace llvm::omp;
44
45//===----------------------------------------------------------------------===//
46// Stack of data-sharing attributes for variables
47//===----------------------------------------------------------------------===//
48
49static const Expr *checkMapClauseExpressionBase(
50 Sema &SemaRef, Expr *E,
51 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
52 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose);
53
54namespace {
55/// Default data sharing attributes, which can be applied to directive.
56enum DefaultDataSharingAttributes {
57 DSA_unspecified = 0, /// Data sharing attribute not specified.
58 DSA_none = 1 << 0, /// Default data sharing attribute 'none'.
59 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'.
60 DSA_firstprivate = 1 << 2, /// Default data sharing attribute 'firstprivate'.
61};
62
63/// Stack for tracking declarations used in OpenMP directives and
64/// clauses and their data-sharing attributes.
65class DSAStackTy {
66public:
67 struct DSAVarData {
68 OpenMPDirectiveKind DKind = OMPD_unknown;
69 OpenMPClauseKind CKind = OMPC_unknown;
70 unsigned Modifier = 0;
71 const Expr *RefExpr = nullptr;
72 DeclRefExpr *PrivateCopy = nullptr;
73 SourceLocation ImplicitDSALoc;
74 bool AppliedToPointee = false;
75 DSAVarData() = default;
76 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
77 const Expr *RefExpr, DeclRefExpr *PrivateCopy,
78 SourceLocation ImplicitDSALoc, unsigned Modifier,
79 bool AppliedToPointee)
80 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
81 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
82 AppliedToPointee(AppliedToPointee) {}
83 };
84 using OperatorOffsetTy =
85 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
86 using DoacrossDependMapTy =
87 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
88 /// Kind of the declaration used in the uses_allocators clauses.
89 enum class UsesAllocatorsDeclKind {
90 /// Predefined allocator
91 PredefinedAllocator,
92 /// User-defined allocator
93 UserDefinedAllocator,
94 /// The declaration that represent allocator trait
95 AllocatorTrait,
96 };
97
98private:
99 struct DSAInfo {
100 OpenMPClauseKind Attributes = OMPC_unknown;
101 unsigned Modifier = 0;
102 /// Pointer to a reference expression and a flag which shows that the
103 /// variable is marked as lastprivate(true) or not (false).
104 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
105 DeclRefExpr *PrivateCopy = nullptr;
106 /// true if the attribute is applied to the pointee, not the variable
107 /// itself.
108 bool AppliedToPointee = false;
109 };
110 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
111 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
112 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
113 using LoopControlVariablesMapTy =
114 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
115 /// Struct that associates a component with the clause kind where they are
116 /// found.
117 struct MappedExprComponentTy {
118 OMPClauseMappableExprCommon::MappableExprComponentLists Components;
119 OpenMPClauseKind Kind = OMPC_unknown;
120 };
121 using MappedExprComponentsTy =
122 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
123 using CriticalsWithHintsTy =
124 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
125 struct ReductionData {
126 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
127 SourceRange ReductionRange;
128 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
129 ReductionData() = default;
130 void set(BinaryOperatorKind BO, SourceRange RR) {
131 ReductionRange = RR;
132 ReductionOp = BO;
133 }
134 void set(const Expr *RefExpr, SourceRange RR) {
135 ReductionRange = RR;
136 ReductionOp = RefExpr;
137 }
138 };
139 using DeclReductionMapTy =
140 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
141 struct DefaultmapInfo {
142 OpenMPDefaultmapClauseModifier ImplicitBehavior =
143 OMPC_DEFAULTMAP_MODIFIER_unknown;
144 SourceLocation SLoc;
145 DefaultmapInfo() = default;
146 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc)
147 : ImplicitBehavior(M), SLoc(Loc) {}
148 };
149
150 struct SharingMapTy {
151 DeclSAMapTy SharingMap;
152 DeclReductionMapTy ReductionMap;
153 UsedRefMapTy AlignedMap;
154 UsedRefMapTy NontemporalMap;
155 MappedExprComponentsTy MappedExprComponents;
156 LoopControlVariablesMapTy LCVMap;
157 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
158 SourceLocation DefaultAttrLoc;
159 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown];
160 OpenMPDirectiveKind Directive = OMPD_unknown;
161 DeclarationNameInfo DirectiveName;
162 Scope *CurScope = nullptr;
163 DeclContext *Context = nullptr;
164 SourceLocation ConstructLoc;
165 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
166 /// get the data (loop counters etc.) about enclosing loop-based construct.
167 /// This data is required during codegen.
168 DoacrossDependMapTy DoacrossDepends;
169 /// First argument (Expr *) contains optional argument of the
170 /// 'ordered' clause, the second one is true if the regions has 'ordered'
171 /// clause, false otherwise.
172 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
173 unsigned AssociatedLoops = 1;
174 bool HasMutipleLoops = false;
175 const Decl *PossiblyLoopCounter = nullptr;
176 bool NowaitRegion = false;
177 bool CancelRegion = false;
178 bool LoopStart = false;
179 bool BodyComplete = false;
180 SourceLocation PrevScanLocation;
181 SourceLocation PrevOrderedLocation;
182 SourceLocation InnerTeamsRegionLoc;
183 /// Reference to the taskgroup task_reduction reference expression.
184 Expr *TaskgroupReductionRef = nullptr;
185 llvm::DenseSet<QualType> MappedClassesQualTypes;
186 SmallVector<Expr *, 4> InnerUsedAllocators;
187 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates;
188 /// List of globals marked as declare target link in this target region
189 /// (isOpenMPTargetExecutionDirective(Directive) == true).
190 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
191 /// List of decls used in inclusive/exclusive clauses of the scan directive.
192 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective;
193 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
194 UsesAllocatorsDecls;
195 Expr *DeclareMapperVar = nullptr;
196 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
197 Scope *CurScope, SourceLocation Loc)
198 : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
199 ConstructLoc(Loc) {}
200 SharingMapTy() = default;
201 };
202
203 using StackTy = SmallVector<SharingMapTy, 4>;
204
205 /// Stack of used declaration and their data-sharing attributes.
206 DeclSAMapTy Threadprivates;
207 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
208 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
209 /// true, if check for DSA must be from parent directive, false, if
210 /// from current directive.
211 OpenMPClauseKind ClauseKindMode = OMPC_unknown;
212 Sema &SemaRef;
213 bool ForceCapturing = false;
214 /// true if all the variables in the target executable directives must be
215 /// captured by reference.
216 bool ForceCaptureByReferenceInTargetExecutable = false;
217 CriticalsWithHintsTy Criticals;
218 unsigned IgnoredStackElements = 0;
219
220 /// Iterators over the stack iterate in order from innermost to outermost
221 /// directive.
222 using const_iterator = StackTy::const_reverse_iterator;
223 const_iterator begin() const {
224 return Stack.empty() ? const_iterator()
225 : Stack.back().first.rbegin() + IgnoredStackElements;
226 }
227 const_iterator end() const {
228 return Stack.empty() ? const_iterator() : Stack.back().first.rend();
229 }
230 using iterator = StackTy::reverse_iterator;
231 iterator begin() {
232 return Stack.empty() ? iterator()
233 : Stack.back().first.rbegin() + IgnoredStackElements;
234 }
235 iterator end() {
236 return Stack.empty() ? iterator() : Stack.back().first.rend();
237 }
238
239 // Convenience operations to get at the elements of the stack.
240
241 bool isStackEmpty() const {
242 return Stack.empty() ||
243 Stack.back().second != CurrentNonCapturingFunctionScope ||
244 Stack.back().first.size() <= IgnoredStackElements;
245 }
246 size_t getStackSize() const {
247 return isStackEmpty() ? 0
248 : Stack.back().first.size() - IgnoredStackElements;
249 }
250
251 SharingMapTy *getTopOfStackOrNull() {
252 size_t Size = getStackSize();
253 if (Size == 0)
254 return nullptr;
255 return &Stack.back().first[Size - 1];
256 }
257 const SharingMapTy *getTopOfStackOrNull() const {
258 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull();
259 }
260 SharingMapTy &getTopOfStack() {
261 assert(!isStackEmpty() && "no current directive");
262 return *getTopOfStackOrNull();
263 }
264 const SharingMapTy &getTopOfStack() const {
265 return const_cast<DSAStackTy&>(*this).getTopOfStack();
266 }
267
268 SharingMapTy *getSecondOnStackOrNull() {
269 size_t Size = getStackSize();
270 if (Size <= 1)
271 return nullptr;
272 return &Stack.back().first[Size - 2];
273 }
274 const SharingMapTy *getSecondOnStackOrNull() const {
275 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull();
276 }
277
278 /// Get the stack element at a certain level (previously returned by
279 /// \c getNestingLevel).
280 ///
281 /// Note that nesting levels count from outermost to innermost, and this is
282 /// the reverse of our iteration order where new inner levels are pushed at
283 /// the front of the stack.
284 SharingMapTy &getStackElemAtLevel(unsigned Level) {
285 assert(Level < getStackSize() && "no such stack element");
286 return Stack.back().first[Level];
287 }
288 const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
289 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level);
290 }
291
292 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
293
294 /// Checks if the variable is a local for OpenMP region.
295 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
296
297 /// Vector of previously declared requires directives
298 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
299 /// omp_allocator_handle_t type.
300 QualType OMPAllocatorHandleT;
301 /// omp_depend_t type.
302 QualType OMPDependT;
303 /// omp_event_handle_t type.
304 QualType OMPEventHandleT;
305 /// omp_alloctrait_t type.
306 QualType OMPAlloctraitT;
307 /// Expression for the predefined allocators.
308 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
309 nullptr};
310 /// Vector of previously encountered target directives
311 SmallVector<SourceLocation, 2> TargetLocations;
312 SourceLocation AtomicLocation;
313
314public:
315 explicit DSAStackTy(Sema &S) : SemaRef(S) {}
316
317 /// Sets omp_allocator_handle_t type.
318 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
319 /// Gets omp_allocator_handle_t type.
320 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
321 /// Sets omp_alloctrait_t type.
322 void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; }
323 /// Gets omp_alloctrait_t type.
324 QualType getOMPAlloctraitT() const { return OMPAlloctraitT; }
325 /// Sets the given default allocator.
326 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
327 Expr *Allocator) {
328 OMPPredefinedAllocators[AllocatorKind] = Allocator;
329 }
330 /// Returns the specified default allocator.
331 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
332 return OMPPredefinedAllocators[AllocatorKind];
333 }
334 /// Sets omp_depend_t type.
335 void setOMPDependT(QualType Ty) { OMPDependT = Ty; }
336 /// Gets omp_depend_t type.
337 QualType getOMPDependT() const { return OMPDependT; }
338
339 /// Sets omp_event_handle_t type.
340 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; }
341 /// Gets omp_event_handle_t type.
342 QualType getOMPEventHandleT() const { return OMPEventHandleT; }
343
344 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
345 OpenMPClauseKind getClauseParsingMode() const {
346 assert(isClauseParsingMode() && "Must be in clause parsing mode.");
347 return ClauseKindMode;
348 }
349 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
350
351 bool isBodyComplete() const {
352 const SharingMapTy *Top = getTopOfStackOrNull();
353 return Top && Top->BodyComplete;
354 }
355 void setBodyComplete() {
356 getTopOfStack().BodyComplete = true;
357 }
358
359 bool isForceVarCapturing() const { return ForceCapturing; }
360 void setForceVarCapturing(bool V) { ForceCapturing = V; }
361
362 void setForceCaptureByReferenceInTargetExecutable(bool V) {
363 ForceCaptureByReferenceInTargetExecutable = V;
364 }
365 bool isForceCaptureByReferenceInTargetExecutable() const {
366 return ForceCaptureByReferenceInTargetExecutable;
367 }
368
369 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
370 Scope *CurScope, SourceLocation Loc) {
371 assert(!IgnoredStackElements &&
372 "cannot change stack while ignoring elements");
373 if (Stack.empty() ||
374 Stack.back().second != CurrentNonCapturingFunctionScope)
375 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
376 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
377 Stack.back().first.back().DefaultAttrLoc = Loc;
378 }
379
380 void pop() {
381 assert(!IgnoredStackElements &&
382 "cannot change stack while ignoring elements");
383 assert(!Stack.back().first.empty() &&
384 "Data-sharing attributes stack is empty!");
385 Stack.back().first.pop_back();
386 }
387
388 /// RAII object to temporarily leave the scope of a directive when we want to
389 /// logically operate in its parent.
390 class ParentDirectiveScope {
391 DSAStackTy &Self;
392 bool Active;
393 public:
394 ParentDirectiveScope(DSAStackTy &Self, bool Activate)
395 : Self(Self), Active(false) {
396 if (Activate)
397 enable();
398 }
399 ~ParentDirectiveScope() { disable(); }
400 void disable() {
401 if (Active) {
402 --Self.IgnoredStackElements;
403 Active = false;
404 }
405 }
406 void enable() {
407 if (!Active) {
408 ++Self.IgnoredStackElements;
409 Active = true;
410 }
411 }
412 };
413
414 /// Marks that we're started loop parsing.
415 void loopInit() {
416 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
417 "Expected loop-based directive.");
418 getTopOfStack().LoopStart = true;
419 }
420 /// Start capturing of the variables in the loop context.
421 void loopStart() {
422 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
423 "Expected loop-based directive.");
424 getTopOfStack().LoopStart = false;
425 }
426 /// true, if variables are captured, false otherwise.
427 bool isLoopStarted() const {
428 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
429 "Expected loop-based directive.");
430 return !getTopOfStack().LoopStart;
431 }
432 /// Marks (or clears) declaration as possibly loop counter.
433 void resetPossibleLoopCounter(const Decl *D = nullptr) {
434 getTopOfStack().PossiblyLoopCounter =
435 D ? D->getCanonicalDecl() : D;
436 }
437 /// Gets the possible loop counter decl.
438 const Decl *getPossiblyLoopCunter() const {
439 return getTopOfStack().PossiblyLoopCounter;
440 }
441 /// Start new OpenMP region stack in new non-capturing function.
442 void pushFunction() {
443 assert(!IgnoredStackElements &&
444 "cannot change stack while ignoring elements");
445 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
446 assert(!isa<CapturingScopeInfo>(CurFnScope));
447 CurrentNonCapturingFunctionScope = CurFnScope;
448 }
449 /// Pop region stack for non-capturing function.
450 void popFunction(const FunctionScopeInfo *OldFSI) {
451 assert(!IgnoredStackElements &&
452 "cannot change stack while ignoring elements");
453 if (!Stack.empty() && Stack.back().second == OldFSI) {
454 assert(Stack.back().first.empty());
455 Stack.pop_back();
456 }
457 CurrentNonCapturingFunctionScope = nullptr;
458 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
459 if (!isa<CapturingScopeInfo>(FSI)) {
460 CurrentNonCapturingFunctionScope = FSI;
461 break;
462 }
463 }
464 }
465
466 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
467 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
468 }
469 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
470 getCriticalWithHint(const DeclarationNameInfo &Name) const {
471 auto I = Criticals.find(Name.getAsString());
472 if (I != Criticals.end())
473 return I->second;
474 return std::make_pair(nullptr, llvm::APSInt());
475 }
476 /// If 'aligned' declaration for given variable \a D was not seen yet,
477 /// add it and return NULL; otherwise return previous occurrence's expression
478 /// for diagnostics.
479 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
480 /// If 'nontemporal' declaration for given variable \a D was not seen yet,
481 /// add it and return NULL; otherwise return previous occurrence's expression
482 /// for diagnostics.
483 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
484
485 /// Register specified variable as loop control variable.
486 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
487 /// Check if the specified variable is a loop control variable for
488 /// current region.
489 /// \return The index of the loop control variable in the list of associated
490 /// for-loops (from outer to inner).
491 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
492 /// Check if the specified variable is a loop control variable for
493 /// parent region.
494 /// \return The index of the loop control variable in the list of associated
495 /// for-loops (from outer to inner).
496 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
497 /// Check if the specified variable is a loop control variable for
498 /// current region.
499 /// \return The index of the loop control variable in the list of associated
500 /// for-loops (from outer to inner).
501 const LCDeclInfo isLoopControlVariable(const ValueDecl *D,
502 unsigned Level) const;
503 /// Get the loop control variable for the I-th loop (or nullptr) in
504 /// parent directive.
505 const ValueDecl *getParentLoopControlVariable(unsigned I) const;
506
507 /// Marks the specified decl \p D as used in scan directive.
508 void markDeclAsUsedInScanDirective(ValueDecl *D) {
509 if (SharingMapTy *Stack = getSecondOnStackOrNull())
510 Stack->UsedInScanDirective.insert(D);
511 }
512
513 /// Checks if the specified declaration was used in the inner scan directive.
514 bool isUsedInScanDirective(ValueDecl *D) const {
515 if (const SharingMapTy *Stack = getTopOfStackOrNull())
516 return Stack->UsedInScanDirective.count(D) > 0;
517 return false;
518 }
519
520 /// Adds explicit data sharing attribute to the specified declaration.
521 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
522 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0,
523 bool AppliedToPointee = false);
524
525 /// Adds additional information for the reduction items with the reduction id
526 /// represented as an operator.
527 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
528 BinaryOperatorKind BOK);
529 /// Adds additional information for the reduction items with the reduction id
530 /// represented as reduction identifier.
531 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
532 const Expr *ReductionRef);
533 /// Returns the location and reduction operation from the innermost parent
534 /// region for the given \p D.
535 const DSAVarData
536 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
537 BinaryOperatorKind &BOK,
538 Expr *&TaskgroupDescriptor) const;
539 /// Returns the location and reduction operation from the innermost parent
540 /// region for the given \p D.
541 const DSAVarData
542 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
543 const Expr *&ReductionRef,
544 Expr *&TaskgroupDescriptor) const;
545 /// Return reduction reference expression for the current taskgroup or
546 /// parallel/worksharing directives with task reductions.
547 Expr *getTaskgroupReductionRef() const {
548 assert((getTopOfStack().Directive == OMPD_taskgroup ||
549 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
550 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
551 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
552 "taskgroup reference expression requested for non taskgroup or "
553 "parallel/worksharing directive.");
554 return getTopOfStack().TaskgroupReductionRef;
555 }
556 /// Checks if the given \p VD declaration is actually a taskgroup reduction
557 /// descriptor variable at the \p Level of OpenMP regions.
558 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
559 return getStackElemAtLevel(Level).TaskgroupReductionRef &&
560 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
561 ->getDecl() == VD;
562 }
563
564 /// Returns data sharing attributes from top of the stack for the
565 /// specified declaration.
566 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
567 /// Returns data-sharing attributes for the specified declaration.
568 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
569 /// Returns data-sharing attributes for the specified declaration.
570 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const;
571 /// Checks if the specified variables has data-sharing attributes which
572 /// match specified \a CPred predicate in any directive which matches \a DPred
573 /// predicate.
574 const DSAVarData
575 hasDSA(ValueDecl *D,
576 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
577 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
578 bool FromParent) const;
579 /// Checks if the specified variables has data-sharing attributes which
580 /// match specified \a CPred predicate in any innermost directive which
581 /// matches \a DPred predicate.
582 const DSAVarData
583 hasInnermostDSA(ValueDecl *D,
584 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
585 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
586 bool FromParent) const;
587 /// Checks if the specified variables has explicit data-sharing
588 /// attributes which match specified \a CPred predicate at the specified
589 /// OpenMP region.
590 bool
591 hasExplicitDSA(const ValueDecl *D,
592 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
593 unsigned Level, bool NotLastprivate = false) const;
594
595 /// Returns true if the directive at level \Level matches in the
596 /// specified \a DPred predicate.
597 bool hasExplicitDirective(
598 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
599 unsigned Level) const;
600
601 /// Finds a directive which matches specified \a DPred predicate.
602 bool hasDirective(
603 const llvm::function_ref<bool(
604 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
605 DPred,
606 bool FromParent) const;
607
608 /// Returns currently analyzed directive.
609 OpenMPDirectiveKind getCurrentDirective() const {
610 const SharingMapTy *Top = getTopOfStackOrNull();
611 return Top ? Top->Directive : OMPD_unknown;
612 }
613 /// Returns directive kind at specified level.
614 OpenMPDirectiveKind getDirective(unsigned Level) const {
615 assert(!isStackEmpty() && "No directive at specified level.");
616 return getStackElemAtLevel(Level).Directive;
617 }
618 /// Returns the capture region at the specified level.
619 OpenMPDirectiveKind getCaptureRegion(unsigned Level,
620 unsigned OpenMPCaptureLevel) const {
621 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
622 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
623 return CaptureRegions[OpenMPCaptureLevel];
624 }
625 /// Returns parent directive.
626 OpenMPDirectiveKind getParentDirective() const {
627 const SharingMapTy *Parent = getSecondOnStackOrNull();
628 return Parent ? Parent->Directive : OMPD_unknown;
629 }
630
631 /// Add requires decl to internal vector
632 void addRequiresDecl(OMPRequiresDecl *RD) {
633 RequiresDecls.push_back(RD);
634 }
635
636 /// Checks if the defined 'requires' directive has specified type of clause.
637 template <typename ClauseType>
638 bool hasRequiresDeclWithClause() const {
639 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
640 return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
641 return isa<ClauseType>(C);
642 });
643 });
644 }
645
646 /// Checks for a duplicate clause amongst previously declared requires
647 /// directives
648 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
649 bool IsDuplicate = false;
650 for (OMPClause *CNew : ClauseList) {
651 for (const OMPRequiresDecl *D : RequiresDecls) {
652 for (const OMPClause *CPrev : D->clauselists()) {
653 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
654 SemaRef.Diag(CNew->getBeginLoc(),
655 diag::err_omp_requires_clause_redeclaration)
656 << getOpenMPClauseName(CNew->getClauseKind());
657 SemaRef.Diag(CPrev->getBeginLoc(),
658 diag::note_omp_requires_previous_clause)
659 << getOpenMPClauseName(CPrev->getClauseKind());
660 IsDuplicate = true;
661 }
662 }
663 }
664 }
665 return IsDuplicate;
666 }
667
668 /// Add location of previously encountered target to internal vector
669 void addTargetDirLocation(SourceLocation LocStart) {
670 TargetLocations.push_back(LocStart);
671 }
672
673 /// Add location for the first encountered atomicc directive.
674 void addAtomicDirectiveLoc(SourceLocation Loc) {
675 if (AtomicLocation.isInvalid())
676 AtomicLocation = Loc;
677 }
678
679 /// Returns the location of the first encountered atomic directive in the
680 /// module.
681 SourceLocation getAtomicDirectiveLoc() const {
682 return AtomicLocation;
683 }
684
685 // Return previously encountered target region locations.
686 ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
687 return TargetLocations;
688 }
689
690 /// Set default data sharing attribute to none.
691 void setDefaultDSANone(SourceLocation Loc) {
692 getTopOfStack().DefaultAttr = DSA_none;
693 getTopOfStack().DefaultAttrLoc = Loc;
694 }
695 /// Set default data sharing attribute to shared.
696 void setDefaultDSAShared(SourceLocation Loc) {
697 getTopOfStack().DefaultAttr = DSA_shared;
698 getTopOfStack().DefaultAttrLoc = Loc;
699 }
700 /// Set default data sharing attribute to firstprivate.
701 void setDefaultDSAFirstPrivate(SourceLocation Loc) {
702 getTopOfStack().DefaultAttr = DSA_firstprivate;
703 getTopOfStack().DefaultAttrLoc = Loc;
704 }
705 /// Set default data mapping attribute to Modifier:Kind
706 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
707 OpenMPDefaultmapClauseKind Kind,
708 SourceLocation Loc) {
709 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
710 DMI.ImplicitBehavior = M;
711 DMI.SLoc = Loc;
712 }
713 /// Check whether the implicit-behavior has been set in defaultmap
714 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
715 if (VariableCategory == OMPC_DEFAULTMAP_unknown)
716 return getTopOfStack()
717 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
718 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
719 getTopOfStack()
720 .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
721 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
722 getTopOfStack()
723 .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
724 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown;
725 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
726 OMPC_DEFAULTMAP_MODIFIER_unknown;
727 }
728
729 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const {
730 return getStackSize() <= Level ? DSA_unspecified
731 : getStackElemAtLevel(Level).DefaultAttr;
732 }
733 DefaultDataSharingAttributes getDefaultDSA() const {
734 return isStackEmpty() ? DSA_unspecified
735 : getTopOfStack().DefaultAttr;
736 }
737 SourceLocation getDefaultDSALocation() const {
738 return isStackEmpty() ? SourceLocation()
739 : getTopOfStack().DefaultAttrLoc;
740 }
741 OpenMPDefaultmapClauseModifier
742 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
743 return isStackEmpty()
744 ? OMPC_DEFAULTMAP_MODIFIER_unknown
745 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
746 }
747 OpenMPDefaultmapClauseModifier
748 getDefaultmapModifierAtLevel(unsigned Level,
749 OpenMPDefaultmapClauseKind Kind) const {
750 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
751 }
752 bool isDefaultmapCapturedByRef(unsigned Level,
753 OpenMPDefaultmapClauseKind Kind) const {
754 OpenMPDefaultmapClauseModifier M =
755 getDefaultmapModifierAtLevel(Level, Kind);
756 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
757 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
758 (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
759 (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
760 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
761 }
762 return true;
763 }
764 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
765 OpenMPDefaultmapClauseKind Kind) {
766 switch (Kind) {
767 case OMPC_DEFAULTMAP_scalar:
768 case OMPC_DEFAULTMAP_pointer:
769 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
770 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
771 (M == OMPC_DEFAULTMAP_MODIFIER_default);
772 case OMPC_DEFAULTMAP_aggregate:
773 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
774 default:
775 break;
776 }
777 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum");
778 }
779 bool mustBeFirstprivateAtLevel(unsigned Level,
780 OpenMPDefaultmapClauseKind Kind) const {
781 OpenMPDefaultmapClauseModifier M =
782 getDefaultmapModifierAtLevel(Level, Kind);
783 return mustBeFirstprivateBase(M, Kind);
784 }
785 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
786 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
787 return mustBeFirstprivateBase(M, Kind);
788 }
789
790 /// Checks if the specified variable is a threadprivate.
791 bool isThreadPrivate(VarDecl *D) {
792 const DSAVarData DVar = getTopDSA(D, false);
793 return isOpenMPThreadPrivate(DVar.CKind);
794 }
795
796 /// Marks current region as ordered (it has an 'ordered' clause).
797 void setOrderedRegion(bool IsOrdered, const Expr *Param,
798 OMPOrderedClause *Clause) {
799 if (IsOrdered)
800 getTopOfStack().OrderedRegion.emplace(Param, Clause);
801 else
802 getTopOfStack().OrderedRegion.reset();
803 }
804 /// Returns true, if region is ordered (has associated 'ordered' clause),
805 /// false - otherwise.
806 bool isOrderedRegion() const {
807 if (const SharingMapTy *Top = getTopOfStackOrNull())
808 return Top->OrderedRegion.hasValue();
809 return false;
810 }
811 /// Returns optional parameter for the ordered region.
812 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
813 if (const SharingMapTy *Top = getTopOfStackOrNull())
814 if (Top->OrderedRegion.hasValue())
815 return Top->OrderedRegion.getValue();
816 return std::make_pair(nullptr, nullptr);
817 }
818 /// Returns true, if parent region is ordered (has associated
819 /// 'ordered' clause), false - otherwise.
820 bool isParentOrderedRegion() const {
821 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
822 return Parent->OrderedRegion.hasValue();
823 return false;
824 }
825 /// Returns optional parameter for the ordered region.
826 std::pair<const Expr *, OMPOrderedClause *>
827 getParentOrderedRegionParam() const {
828 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
829 if (Parent->OrderedRegion.hasValue())
830 return Parent->OrderedRegion.getValue();
831 return std::make_pair(nullptr, nullptr);
832 }
833 /// Marks current region as nowait (it has a 'nowait' clause).
834 void setNowaitRegion(bool IsNowait = true) {
835 getTopOfStack().NowaitRegion = IsNowait;
836 }
837 /// Returns true, if parent region is nowait (has associated
838 /// 'nowait' clause), false - otherwise.
839 bool isParentNowaitRegion() const {
840 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
841 return Parent->NowaitRegion;
842 return false;
843 }
844 /// Marks parent region as cancel region.
845 void setParentCancelRegion(bool Cancel = true) {
846 if (SharingMapTy *Parent = getSecondOnStackOrNull())
847 Parent->CancelRegion |= Cancel;
848 }
849 /// Return true if current region has inner cancel construct.
850 bool isCancelRegion() const {
851 const SharingMapTy *Top = getTopOfStackOrNull();
852 return Top ? Top->CancelRegion : false;
853 }
854
855 /// Mark that parent region already has scan directive.
856 void setParentHasScanDirective(SourceLocation Loc) {
857 if (SharingMapTy *Parent = getSecondOnStackOrNull())
858 Parent->PrevScanLocation = Loc;
859 }
860 /// Return true if current region has inner cancel construct.
861 bool doesParentHasScanDirective() const {
862 const SharingMapTy *Top = getSecondOnStackOrNull();
863 return Top ? Top->PrevScanLocation.isValid() : false;
864 }
865 /// Return true if current region has inner cancel construct.
866 SourceLocation getParentScanDirectiveLoc() const {
867 const SharingMapTy *Top = getSecondOnStackOrNull();
868 return Top ? Top->PrevScanLocation : SourceLocation();
869 }
870 /// Mark that parent region already has ordered directive.
871 void setParentHasOrderedDirective(SourceLocation Loc) {
872 if (SharingMapTy *Parent = getSecondOnStackOrNull())
873 Parent->PrevOrderedLocation = Loc;
874 }
875 /// Return true if current region has inner ordered construct.
876 bool doesParentHasOrderedDirective() const {
877 const SharingMapTy *Top = getSecondOnStackOrNull();
878 return Top ? Top->PrevOrderedLocation.isValid() : false;
879 }
880 /// Returns the location of the previously specified ordered directive.
881 SourceLocation getParentOrderedDirectiveLoc() const {
882 const SharingMapTy *Top = getSecondOnStackOrNull();
883 return Top ? Top->PrevOrderedLocation : SourceLocation();
884 }
885
886 /// Set collapse value for the region.
887 void setAssociatedLoops(unsigned Val) {
888 getTopOfStack().AssociatedLoops = Val;
889 if (Val > 1)
890 getTopOfStack().HasMutipleLoops = true;
891 }
892 /// Return collapse value for region.
893 unsigned getAssociatedLoops() const {
894 const SharingMapTy *Top = getTopOfStackOrNull();
895 return Top ? Top->AssociatedLoops : 0;
896 }
897 /// Returns true if the construct is associated with multiple loops.
898 bool hasMutipleLoops() const {
899 const SharingMapTy *Top = getTopOfStackOrNull();
900 return Top ? Top->HasMutipleLoops : false;
901 }
902
903 /// Marks current target region as one with closely nested teams
904 /// region.
905 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
906 if (SharingMapTy *Parent = getSecondOnStackOrNull())
907 Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
908 }
909 /// Returns true, if current region has closely nested teams region.
910 bool hasInnerTeamsRegion() const {
911 return getInnerTeamsRegionLoc().isValid();
912 }
913 /// Returns location of the nested teams region (if any).
914 SourceLocation getInnerTeamsRegionLoc() const {
915 const SharingMapTy *Top = getTopOfStackOrNull();
916 return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
917 }
918
919 Scope *getCurScope() const {
920 const SharingMapTy *Top = getTopOfStackOrNull();
921 return Top ? Top->CurScope : nullptr;
922 }
923 void setContext(DeclContext *DC) { getTopOfStack().Context = DC; }
924 SourceLocation getConstructLoc() const {
925 const SharingMapTy *Top = getTopOfStackOrNull();
926 return Top ? Top->ConstructLoc : SourceLocation();
927 }
928
929 /// Do the check specified in \a Check to all component lists and return true
930 /// if any issue is found.
931 bool checkMappableExprComponentListsForDecl(
932 const ValueDecl *VD, bool CurrentRegionOnly,
933 const llvm::function_ref<
934 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
935 OpenMPClauseKind)>
936 Check) const {
937 if (isStackEmpty())
938 return false;
939 auto SI = begin();
940 auto SE = end();
941
942 if (SI == SE)
943 return false;
944
945 if (CurrentRegionOnly)
946 SE = std::next(SI);
947 else
948 std::advance(SI, 1);
949
950 for (; SI != SE; ++SI) {
951 auto MI = SI->MappedExprComponents.find(VD);
952 if (MI != SI->MappedExprComponents.end())
953 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
954 MI->second.Components)
955 if (Check(L, MI->second.Kind))
956 return true;
957 }
958 return false;
959 }
960
961 /// Do the check specified in \a Check to all component lists at a given level
962 /// and return true if any issue is found.
963 bool checkMappableExprComponentListsForDeclAtLevel(
964 const ValueDecl *VD, unsigned Level,
965 const llvm::function_ref<
966 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
967 OpenMPClauseKind)>
968 Check) const {
969 if (getStackSize() <= Level)
970 return false;
971
972 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
973 auto MI = StackElem.MappedExprComponents.find(VD);
974 if (MI != StackElem.MappedExprComponents.end())
975 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
976 MI->second.Components)
977 if (Check(L, MI->second.Kind))
978 return true;
979 return false;
980 }
981
982 /// Create a new mappable expression component list associated with a given
983 /// declaration and initialize it with the provided list of components.
984 void addMappableExpressionComponents(
985 const ValueDecl *VD,
986 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
987 OpenMPClauseKind WhereFoundClauseKind) {
988 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
989 // Create new entry and append the new components there.
990 MEC.Components.resize(MEC.Components.size() + 1);
991 MEC.Components.back().append(Components.begin(), Components.end());
992 MEC.Kind = WhereFoundClauseKind;
993 }
994
995 unsigned getNestingLevel() const {
996 assert(!isStackEmpty());
997 return getStackSize() - 1;
998 }
999 void addDoacrossDependClause(OMPDependClause *C,
1000 const OperatorOffsetTy &OpsOffs) {
1001 SharingMapTy *Parent = getSecondOnStackOrNull();
1002 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive));
1003 Parent->DoacrossDepends.try_emplace(C, OpsOffs);
1004 }
1005 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
1006 getDoacrossDependClauses() const {
1007 const SharingMapTy &StackElem = getTopOfStack();
1008 if (isOpenMPWorksharingDirective(StackElem.Directive)) {
1009 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
1010 return llvm::make_range(Ref.begin(), Ref.end());
1011 }
1012 return llvm::make_range(StackElem.DoacrossDepends.end(),
1013 StackElem.DoacrossDepends.end());
1014 }
1015
1016 // Store types of classes which have been explicitly mapped
1017 void addMappedClassesQualTypes(QualType QT) {
1018 SharingMapTy &StackElem = getTopOfStack();
1019 StackElem.MappedClassesQualTypes.insert(QT);
1020 }
1021
1022 // Return set of mapped classes types
1023 bool isClassPreviouslyMapped(QualType QT) const {
1024 const SharingMapTy &StackElem = getTopOfStack();
1025 return StackElem.MappedClassesQualTypes.count(QT) != 0;
1026 }
1027
1028 /// Adds global declare target to the parent target region.
1029 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
1030 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1031 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
1032 "Expected declare target link global.");
1033 for (auto &Elem : *this) {
1034 if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
1035 Elem.DeclareTargetLinkVarDecls.push_back(E);
1036 return;
1037 }
1038 }
1039 }
1040
1041 /// Returns the list of globals with declare target link if current directive
1042 /// is target.
1043 ArrayRef<DeclRefExpr *> getLinkGlobals() const {
1044 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
1045 "Expected target executable directive.");
1046 return getTopOfStack().DeclareTargetLinkVarDecls;
1047 }
1048
1049 /// Adds list of allocators expressions.
1050 void addInnerAllocatorExpr(Expr *E) {
1051 getTopOfStack().InnerUsedAllocators.push_back(E);
1052 }
1053 /// Return list of used allocators.
1054 ArrayRef<Expr *> getInnerAllocators() const {
1055 return getTopOfStack().InnerUsedAllocators;
1056 }
1057 /// Marks the declaration as implicitly firstprivate nin the task-based
1058 /// regions.
1059 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) {
1060 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1061 }
1062 /// Checks if the decl is implicitly firstprivate in the task-based region.
1063 bool isImplicitTaskFirstprivate(Decl *D) const {
1064 return getTopOfStack().ImplicitTaskFirstprivates.count(D) > 0;
1065 }
1066
1067 /// Marks decl as used in uses_allocators clause as the allocator.
1068 void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) {
1069 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1070 }
1071 /// Checks if specified decl is used in uses allocator clause as the
1072 /// allocator.
1073 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level,
1074 const Decl *D) const {
1075 const SharingMapTy &StackElem = getTopOfStack();
1076 auto I = StackElem.UsesAllocatorsDecls.find(D);
1077 if (I == StackElem.UsesAllocatorsDecls.end())
1078 return None;
1079 return I->getSecond();
1080 }
1081 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const {
1082 const SharingMapTy &StackElem = getTopOfStack();
1083 auto I = StackElem.UsesAllocatorsDecls.find(D);
1084 if (I == StackElem.UsesAllocatorsDecls.end())
1085 return None;
1086 return I->getSecond();
1087 }
1088
1089 void addDeclareMapperVarRef(Expr *Ref) {
1090 SharingMapTy &StackElem = getTopOfStack();
1091 StackElem.DeclareMapperVar = Ref;
1092 }
1093 const Expr *getDeclareMapperVarRef() const {
1094 const SharingMapTy *Top = getTopOfStackOrNull();
1095 return Top ? Top->DeclareMapperVar : nullptr;
1096 }
1097};
1098
1099bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1100 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
1101}
1102
1103bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1104 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
1105 DKind == OMPD_unknown;
1106}
1107
1108} // namespace
1109
1110static const Expr *getExprAsWritten(const Expr *E) {
1111 if (const auto *FE = dyn_cast<FullExpr>(E))
1112 E = FE->getSubExpr();
1113
1114 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1115 E = MTE->getSubExpr();
1116
1117 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1118 E = Binder->getSubExpr();
1119
1120 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1121 E = ICE->getSubExprAsWritten();
1122 return E->IgnoreParens();
1123}
1124
1125static Expr *getExprAsWritten(Expr *E) {
1126 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
1127}
1128
1129static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
1130 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1131 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
1132 D = ME->getMemberDecl();
1133 const auto *VD = dyn_cast<VarDecl>(D);
1134 const auto *FD = dyn_cast<FieldDecl>(D);
1135 if (VD != nullptr) {
1136 VD = VD->getCanonicalDecl();
1137 D = VD;
1138 } else {
1139 assert(FD);
1140 FD = FD->getCanonicalDecl();
1141 D = FD;
1142 }
1143 return D;
1144}
1145
1146static ValueDecl *getCanonicalDecl(ValueDecl *D) {
1147 return const_cast<ValueDecl *>(
1148 getCanonicalDecl(const_cast<const ValueDecl *>(D)));
1149}
1150
1151DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1152 ValueDecl *D) const {
1153 D = getCanonicalDecl(D);
1154 auto *VD = dyn_cast<VarDecl>(D);
1155 const auto *FD = dyn_cast<FieldDecl>(D);
1156 DSAVarData DVar;
1157 if (Iter == end()) {
1158 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1159 // in a region but not in construct]
1160 // File-scope or namespace-scope variables referenced in called routines
1161 // in the region are shared unless they appear in a threadprivate
1162 // directive.
1163 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
1164 DVar.CKind = OMPC_shared;
1165
1166 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
1167 // in a region but not in construct]
1168 // Variables with static storage duration that are declared in called
1169 // routines in the region are shared.
1170 if (VD && VD->hasGlobalStorage())
1171 DVar.CKind = OMPC_shared;
1172
1173 // Non-static data members are shared by default.
1174 if (FD)
1175 DVar.CKind = OMPC_shared;
1176
1177 return DVar;
1178 }
1179
1180 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1181 // in a Construct, C/C++, predetermined, p.1]
1182 // Variables with automatic storage duration that are declared in a scope
1183 // inside the construct are private.
1184 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
1185 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
1186 DVar.CKind = OMPC_private;
1187 return DVar;
1188 }
1189
1190 DVar.DKind = Iter->Directive;
1191 // Explicitly specified attributes and local variables with predetermined
1192 // attributes.
1193 if (Iter->SharingMap.count(D)) {
1194 const DSAInfo &Data = Iter->SharingMap.lookup(D);
1195 DVar.RefExpr = Data.RefExpr.getPointer();
1196 DVar.PrivateCopy = Data.PrivateCopy;
1197 DVar.CKind = Data.Attributes;
1198 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1199 DVar.Modifier = Data.Modifier;
1200 DVar.AppliedToPointee = Data.AppliedToPointee;
1201 return DVar;
1202 }
1203
1204 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1205 // in a Construct, C/C++, implicitly determined, p.1]
1206 // In a parallel or task construct, the data-sharing attributes of these
1207 // variables are determined by the default clause, if present.
1208 switch (Iter->DefaultAttr) {
1209 case DSA_shared:
1210 DVar.CKind = OMPC_shared;
1211 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1212 return DVar;
1213 case DSA_none:
1214 return DVar;
1215 case DSA_firstprivate:
1216 if (VD->getStorageDuration() == SD_Static &&
1217 VD->getDeclContext()->isFileContext()) {
1218 DVar.CKind = OMPC_unknown;
1219 } else {
1220 DVar.CKind = OMPC_firstprivate;
1221 }
1222 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1223 return DVar;
1224 case DSA_unspecified:
1225 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1226 // in a Construct, implicitly determined, p.2]
1227 // In a parallel construct, if no default clause is present, these
1228 // variables are shared.
1229 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1230 if ((isOpenMPParallelDirective(DVar.DKind) &&
1231 !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1232 isOpenMPTeamsDirective(DVar.DKind)) {
1233 DVar.CKind = OMPC_shared;
1234 return DVar;
1235 }
1236
1237 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1238 // in a Construct, implicitly determined, p.4]
1239 // In a task construct, if no default clause is present, a variable that in
1240 // the enclosing context is determined to be shared by all implicit tasks
1241 // bound to the current team is shared.
1242 if (isOpenMPTaskingDirective(DVar.DKind)) {
1243 DSAVarData DVarTemp;
1244 const_iterator I = Iter, E = end();
1245 do {
1246 ++I;
1247 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1248 // Referenced in a Construct, implicitly determined, p.6]
1249 // In a task construct, if no default clause is present, a variable
1250 // whose data-sharing attribute is not determined by the rules above is
1251 // firstprivate.
1252 DVarTemp = getDSA(I, D);
1253 if (DVarTemp.CKind != OMPC_shared) {
1254 DVar.RefExpr = nullptr;
1255 DVar.CKind = OMPC_firstprivate;
1256 return DVar;
1257 }
1258 } while (I != E && !isImplicitTaskingRegion(I->Directive));
1259 DVar.CKind =
1260 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1261 return DVar;
1262 }
1263 }
1264 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1265 // in a Construct, implicitly determined, p.3]
1266 // For constructs other than task, if no default clause is present, these
1267 // variables inherit their data-sharing attributes from the enclosing
1268 // context.
1269 return getDSA(++Iter, D);
1270}
1271
1272const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1273 const Expr *NewDE) {
1274 assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1275 D = getCanonicalDecl(D);
1276 SharingMapTy &StackElem = getTopOfStack();
1277 auto It = StackElem.AlignedMap.find(D);
1278 if (It == StackElem.AlignedMap.end()) {
1279 assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1280 StackElem.AlignedMap[D] = NewDE;
1281 return nullptr;
1282 }
1283 assert(It->second && "Unexpected nullptr expr in the aligned map");
1284 return It->second;
1285}
1286
1287const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1288 const Expr *NewDE) {
1289 assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1290 D = getCanonicalDecl(D);
1291 SharingMapTy &StackElem = getTopOfStack();
1292 auto It = StackElem.NontemporalMap.find(D);
1293 if (It == StackElem.NontemporalMap.end()) {
1294 assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1295 StackElem.NontemporalMap[D] = NewDE;
1296 return nullptr;
1297 }
1298 assert(It->second && "Unexpected nullptr expr in the aligned map");
1299 return It->second;
1300}
1301
1302void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1303 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1304 D = getCanonicalDecl(D);
1305 SharingMapTy &StackElem = getTopOfStack();
1306 StackElem.LCVMap.try_emplace(
1307 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1308}
1309
1310const DSAStackTy::LCDeclInfo
1311DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1312 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1313 D = getCanonicalDecl(D);
1314 const SharingMapTy &StackElem = getTopOfStack();
1315 auto It = StackElem.LCVMap.find(D);
1316 if (It != StackElem.LCVMap.end())
1317 return It->second;
1318 return {0, nullptr};
1319}
1320
1321const DSAStackTy::LCDeclInfo
1322DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const {
1323 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1324 D = getCanonicalDecl(D);
1325 for (unsigned I = Level + 1; I > 0; --I) {
1326 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1327 auto It = StackElem.LCVMap.find(D);
1328 if (It != StackElem.LCVMap.end())
1329 return It->second;
1330 }
1331 return {0, nullptr};
1332}
1333
1334const DSAStackTy::LCDeclInfo
1335DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1336 const SharingMapTy *Parent = getSecondOnStackOrNull();
1337 assert(Parent && "Data-sharing attributes stack is empty");
1338 D = getCanonicalDecl(D);
1339 auto It = Parent->LCVMap.find(D);
1340 if (It != Parent->LCVMap.end())
1341 return It->second;
1342 return {0, nullptr};
1343}
1344
1345const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1346 const SharingMapTy *Parent = getSecondOnStackOrNull();
1347 assert(Parent && "Data-sharing attributes stack is empty");
1348 if (Parent->LCVMap.size() < I)
1349 return nullptr;
1350 for (const auto &Pair : Parent->LCVMap)
1351 if (Pair.second.first == I)
1352 return Pair.first;
1353 return nullptr;
1354}
1355
1356void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1357 DeclRefExpr *PrivateCopy, unsigned Modifier,
1358 bool AppliedToPointee) {
1359 D = getCanonicalDecl(D);
1360 if (A == OMPC_threadprivate) {
1361 DSAInfo &Data = Threadprivates[D];
1362 Data.Attributes = A;
1363 Data.RefExpr.setPointer(E);
1364 Data.PrivateCopy = nullptr;
1365 Data.Modifier = Modifier;
1366 } else {
1367 DSAInfo &Data = getTopOfStack().SharingMap[D];
1368 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
1369 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
1370 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
1371 (isLoopControlVariable(D).first && A == OMPC_private));
1372 Data.Modifier = Modifier;
1373 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1374 Data.RefExpr.setInt(/*IntVal=*/true);
1375 return;
1376 }
1377 const bool IsLastprivate =
1378 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1379 Data.Attributes = A;
1380 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1381 Data.PrivateCopy = PrivateCopy;
1382 Data.AppliedToPointee = AppliedToPointee;
1383 if (PrivateCopy) {
1384 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1385 Data.Modifier = Modifier;
1386 Data.Attributes = A;
1387 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1388 Data.PrivateCopy = nullptr;
1389 Data.AppliedToPointee = AppliedToPointee;
1390 }
1391 }
1392}
1393
1394/// Build a variable declaration for OpenMP loop iteration variable.
1395static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
1396 StringRef Name, const AttrVec *Attrs = nullptr,
1397 DeclRefExpr *OrigRef = nullptr) {
1398 DeclContext *DC = SemaRef.CurContext;
1399 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1400 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1401 auto *Decl =
1402 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1403 if (Attrs) {
1404 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1405 I != E; ++I)
1406 Decl->addAttr(*I);
1407 }
1408 Decl->setImplicit();
1409 if (OrigRef) {
1410 Decl->addAttr(
1411 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1412 }
1413 return Decl;
1414}
1415
1416static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1417 SourceLocation Loc,
1418 bool RefersToCapture = false) {
1419 D->setReferenced();
1420 D->markUsed(S.Context);
1421 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1422 SourceLocation(), D, RefersToCapture, Loc, Ty,
1423 VK_LValue);
1424}
1425
1426void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1427 BinaryOperatorKind BOK) {
1428 D = getCanonicalDecl(D);
1429 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1430 assert(
1431 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1432 "Additional reduction info may be specified only for reduction items.");
1433 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1434 assert(ReductionData.ReductionRange.isInvalid() &&
1435 (getTopOfStack().Directive == OMPD_taskgroup ||
1436 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1437 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1438 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1439 "Additional reduction info may be specified only once for reduction "
1440 "items.");
1441 ReductionData.set(BOK, SR);
1442 Expr *&TaskgroupReductionRef =
1443 getTopOfStack().TaskgroupReductionRef;
1444 if (!TaskgroupReductionRef) {
1445 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1446 SemaRef.Context.VoidPtrTy, ".task_red.");
1447 TaskgroupReductionRef =
1448 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1449 }
1450}
1451
1452void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1453 const Expr *ReductionRef) {
1454 D = getCanonicalDecl(D);
1455 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1456 assert(
1457 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1458 "Additional reduction info may be specified only for reduction items.");
1459 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1460 assert(ReductionData.ReductionRange.isInvalid() &&
1461 (getTopOfStack().Directive == OMPD_taskgroup ||
1462 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1463 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1464 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1465 "Additional reduction info may be specified only once for reduction "
1466 "items.");
1467 ReductionData.set(ReductionRef, SR);
1468 Expr *&TaskgroupReductionRef =
1469 getTopOfStack().TaskgroupReductionRef;
1470 if (!TaskgroupReductionRef) {
1471 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1472 SemaRef.Context.VoidPtrTy, ".task_red.");
1473 TaskgroupReductionRef =
1474 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1475 }
1476}
1477
1478const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1479 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1480 Expr *&TaskgroupDescriptor) const {
1481 D = getCanonicalDecl(D);
1482 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1483 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1484 const DSAInfo &Data = I->SharingMap.lookup(D);
1485 if (Data.Attributes != OMPC_reduction ||
1486 Data.Modifier != OMPC_REDUCTION_task)
1487 continue;
1488 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1489 if (!ReductionData.ReductionOp ||
1490 ReductionData.ReductionOp.is<const Expr *>())
1491 return DSAVarData();
1492 SR = ReductionData.ReductionRange;
1493 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1494 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1495 "expression for the descriptor is not "
1496 "set.");
1497 TaskgroupDescriptor = I->TaskgroupReductionRef;
1498 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1499 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1500 /*AppliedToPointee=*/false);
1501 }
1502 return DSAVarData();
1503}
1504
1505const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1506 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1507 Expr *&TaskgroupDescriptor) const {
1508 D = getCanonicalDecl(D);
1509 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1510 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1511 const DSAInfo &Data = I->SharingMap.lookup(D);
1512 if (Data.Attributes != OMPC_reduction ||
1513 Data.Modifier != OMPC_REDUCTION_task)
1514 continue;
1515 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1516 if (!ReductionData.ReductionOp ||
1517 !ReductionData.ReductionOp.is<const Expr *>())
1518 return DSAVarData();
1519 SR = ReductionData.ReductionRange;
1520 ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1521 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1522 "expression for the descriptor is not "
1523 "set.");
1524 TaskgroupDescriptor = I->TaskgroupReductionRef;
1525 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1526 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1527 /*AppliedToPointee=*/false);
1528 }
1529 return DSAVarData();
1530}
1531
1532bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1533 D = D->getCanonicalDecl();
1534 for (const_iterator E = end(); I != E; ++I) {
1535 if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1536 isOpenMPTargetExecutionDirective(I->Directive)) {
1537 if (I->CurScope) {
1538 Scope *TopScope = I->CurScope->getParent();
1539 Scope *CurScope = getCurScope();
1540 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1541 CurScope = CurScope->getParent();
1542 return CurScope != TopScope;
1543 }
1544 for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent())
1545 if (I->Context == DC)
1546 return true;
1547 return false;
1548 }
1549 }
1550 return false;
1551}
1552
1553static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1554 bool AcceptIfMutable = true,
1555 bool *IsClassType = nullptr) {
1556 ASTContext &Context = SemaRef.getASTContext();
1557 Type = Type.getNonReferenceType().getCanonicalType();
1558 bool IsConstant = Type.isConstant(Context);
1559 Type = Context.getBaseElementType(Type);
1560 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1561 ? Type->getAsCXXRecordDecl()
1562 : nullptr;
1563 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1564 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1565 RD = CTD->getTemplatedDecl();
1566 if (IsClassType)
1567 *IsClassType = RD;
1568 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1569 RD->hasDefinition() && RD->hasMutableFields());
1570}
1571
1572static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1573 QualType Type, OpenMPClauseKind CKind,
1574 SourceLocation ELoc,
1575 bool AcceptIfMutable = true,
1576 bool ListItemNotVar = false) {
1577 ASTContext &Context = SemaRef.getASTContext();
1578 bool IsClassType;
1579 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1580 unsigned Diag = ListItemNotVar
1581 ? diag::err_omp_const_list_item
1582 : IsClassType ? diag::err_omp_const_not_mutable_variable
1583 : diag::err_omp_const_variable;
1584 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1585 if (!ListItemNotVar && D) {
1586 const VarDecl *VD = dyn_cast<VarDecl>(D);
1587 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1588 VarDecl::DeclarationOnly;
1589 SemaRef.Diag(D->getLocation(),
1590 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1591 << D;
1592 }
1593 return true;
1594 }
1595 return false;
1596}
1597
1598const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1599 bool FromParent) {
1600 D = getCanonicalDecl(D);
1601 DSAVarData DVar;
1602
1603 auto *VD = dyn_cast<VarDecl>(D);
1604 auto TI = Threadprivates.find(D);
1605 if (TI != Threadprivates.end()) {
1606 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1607 DVar.CKind = OMPC_threadprivate;
1608 DVar.Modifier = TI->getSecond().Modifier;
1609 return DVar;
1610 }
1611 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1612 DVar.RefExpr = buildDeclRefExpr(
1613 SemaRef, VD, D->getType().getNonReferenceType(),
1614 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1615 DVar.CKind = OMPC_threadprivate;
1616 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1617 return DVar;
1618 }
1619 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1620 // in a Construct, C/C++, predetermined, p.1]
1621 // Variables appearing in threadprivate directives are threadprivate.
1622 if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1623 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1624 SemaRef.getLangOpts().OpenMPUseTLS &&
1625 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1626 (VD && VD->getStorageClass() == SC_Register &&
1627 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1628 DVar.RefExpr = buildDeclRefExpr(
1629 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1630 DVar.CKind = OMPC_threadprivate;
1631 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1632 return DVar;
1633 }
1634 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1635 VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1636 !isLoopControlVariable(D).first) {
1637 const_iterator IterTarget =
1638 std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1639 return isOpenMPTargetExecutionDirective(Data.Directive);
1640 });
1641 if (IterTarget != end()) {
1642 const_iterator ParentIterTarget = IterTarget + 1;
1643 for (const_iterator Iter = begin();
1644 Iter != ParentIterTarget; ++Iter) {
1645 if (isOpenMPLocal(VD, Iter)) {
1646 DVar.RefExpr =
1647 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1648 D->getLocation());
1649 DVar.CKind = OMPC_threadprivate;
1650 return DVar;
1651 }
1652 }
1653 if (!isClauseParsingMode() || IterTarget != begin()) {
1654 auto DSAIter = IterTarget->SharingMap.find(D);
1655 if (DSAIter != IterTarget->SharingMap.end() &&
1656 isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1657 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1658 DVar.CKind = OMPC_threadprivate;
1659 return DVar;
1660 }
1661 const_iterator End = end();
1662 if (!SemaRef.isOpenMPCapturedByRef(
1663 D, std::distance(ParentIterTarget, End),
1664 /*OpenMPCaptureLevel=*/0)) {
1665 DVar.RefExpr =
1666 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1667 IterTarget->ConstructLoc);
1668 DVar.CKind = OMPC_threadprivate;
1669 return DVar;
1670 }
1671 }
1672 }
1673 }
1674
1675 if (isStackEmpty())
1676 // Not in OpenMP execution region and top scope was already checked.
1677 return DVar;
1678
1679 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1680 // in a Construct, C/C++, predetermined, p.4]
1681 // Static data members are shared.
1682 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1683 // in a Construct, C/C++, predetermined, p.7]
1684 // Variables with static storage duration that are declared in a scope
1685 // inside the construct are shared.
1686 if (VD && VD->isStaticDataMember()) {
1687 // Check for explicitly specified attributes.
1688 const_iterator I = begin();
1689 const_iterator EndI = end();
1690 if (FromParent && I != EndI)
1691 ++I;
1692 if (I != EndI) {
1693 auto It = I->SharingMap.find(D);
1694 if (It != I->SharingMap.end()) {
1695 const DSAInfo &Data = It->getSecond();
1696 DVar.RefExpr = Data.RefExpr.getPointer();
1697 DVar.PrivateCopy = Data.PrivateCopy;
1698 DVar.CKind = Data.Attributes;
1699 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1700 DVar.DKind = I->Directive;
1701 DVar.Modifier = Data.Modifier;
1702 DVar.AppliedToPointee = Data.AppliedToPointee;
1703 return DVar;
1704 }
1705 }
1706
1707 DVar.CKind = OMPC_shared;
1708 return DVar;
1709 }
1710
1711 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1712 // The predetermined shared attribute for const-qualified types having no
1713 // mutable members was removed after OpenMP 3.1.
1714 if (SemaRef.LangOpts.OpenMP <= 31) {
1715 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1716 // in a Construct, C/C++, predetermined, p.6]
1717 // Variables with const qualified type having no mutable member are
1718 // shared.
1719 if (isConstNotMutableType(SemaRef, D->getType())) {
1720 // Variables with const-qualified type having no mutable member may be
1721 // listed in a firstprivate clause, even if they are static data members.
1722 DSAVarData DVarTemp = hasInnermostDSA(
1723 D,
1724 [](OpenMPClauseKind C, bool) {
1725 return C == OMPC_firstprivate || C == OMPC_shared;
1726 },
1727 MatchesAlways, FromParent);
1728 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1729 return DVarTemp;
1730
1731 DVar.CKind = OMPC_shared;
1732 return DVar;
1733 }
1734 }
1735
1736 // Explicitly specified attributes and local variables with predetermined
1737 // attributes.
1738 const_iterator I = begin();
1739 const_iterator EndI = end();
1740 if (FromParent && I != EndI)
1741 ++I;
1742 if (I == EndI)
1743 return DVar;
1744 auto It = I->SharingMap.find(D);
1745 if (It != I->SharingMap.end()) {
1746 const DSAInfo &Data = It->getSecond();
1747 DVar.RefExpr = Data.RefExpr.getPointer();
1748 DVar.PrivateCopy = Data.PrivateCopy;
1749 DVar.CKind = Data.Attributes;
1750 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1751 DVar.DKind = I->Directive;
1752 DVar.Modifier = Data.Modifier;
1753 DVar.AppliedToPointee = Data.AppliedToPointee;
1754 }
1755
1756 return DVar;
1757}
1758
1759const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1760 bool FromParent) const {
1761 if (isStackEmpty()) {
1762 const_iterator I;
1763 return getDSA(I, D);
1764 }
1765 D = getCanonicalDecl(D);
1766 const_iterator StartI = begin();
1767 const_iterator EndI = end();
1768 if (FromParent && StartI != EndI)
1769 ++StartI;
1770 return getDSA(StartI, D);
1771}
1772
1773const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1774 unsigned Level) const {
1775 if (getStackSize() <= Level)
1776 return DSAVarData();
1777 D = getCanonicalDecl(D);
1778 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1779 return getDSA(StartI, D);
1780}
1781
1782const DSAStackTy::DSAVarData
1783DSAStackTy::hasDSA(ValueDecl *D,
1784 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1785 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1786 bool FromParent) const {
1787 if (isStackEmpty())
1788 return {};
1789 D = getCanonicalDecl(D);
1790 const_iterator I = begin();
1791 const_iterator EndI = end();
1792 if (FromParent && I != EndI)
1793 ++I;
1794 for (; I != EndI; ++I) {
1795 if (!DPred(I->Directive) &&
1796 !isImplicitOrExplicitTaskingRegion(I->Directive))
1797 continue;
1798 const_iterator NewI = I;
1799 DSAVarData DVar = getDSA(NewI, D);
1800 if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee))
1801 return DVar;
1802 }
1803 return {};
1804}
1805
1806const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1807 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1808 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1809 bool FromParent) const {
1810 if (isStackEmpty())
1811 return {};
1812 D = getCanonicalDecl(D);
1813 const_iterator StartI = begin();
1814 const_iterator EndI = end();
1815 if (FromParent && StartI != EndI)
1816 ++StartI;
1817 if (StartI == EndI || !DPred(StartI->Directive))
1818 return {};
1819 const_iterator NewI = StartI;
1820 DSAVarData DVar = getDSA(NewI, D);
1821 return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1822 ? DVar
1823 : DSAVarData();
1824}
1825
1826bool DSAStackTy::hasExplicitDSA(
1827 const ValueDecl *D,
1828 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1829 unsigned Level, bool NotLastprivate) const {
1830 if (getStackSize() <= Level)
1831 return false;
1832 D = getCanonicalDecl(D);
1833 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1834 auto I = StackElem.SharingMap.find(D);
1835 if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1836 CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1837 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1838 return true;
1839 // Check predetermined rules for the loop control variables.
1840 auto LI = StackElem.LCVMap.find(D);
1841 if (LI != StackElem.LCVMap.end())
1842 return CPred(OMPC_private, /*AppliedToPointee=*/false);
1843 return false;
1844}
1845
1846bool DSAStackTy::hasExplicitDirective(
1847 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1848 unsigned Level) const {
1849 if (getStackSize() <= Level)
1850 return false;
1851 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1852 return DPred(StackElem.Directive);
1853}
1854
1855bool DSAStackTy::hasDirective(
1856 const llvm::function_ref<bool(OpenMPDirectiveKind,
1857 const DeclarationNameInfo &, SourceLocation)>
1858 DPred,
1859 bool FromParent) const {
1860 // We look only in the enclosing region.
1861 size_t Skip = FromParent ? 2 : 1;
1862 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1863 I != E; ++I) {
1864 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1865 return true;
1866 }
1867 return false;
1868}
1869
1870void Sema::InitDataSharingAttributesStack() {
1871 VarDataSharingAttributesStack = new DSAStackTy(*this);
1872}
1873
1874#define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1875
1876void Sema::pushOpenMPFunctionRegion() {
1877 DSAStack->pushFunction();
1878}
1879
1880void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1881 DSAStack->popFunction(OldFSI);
1882}
1883
1884static bool isOpenMPDeviceDelayedContext(Sema &S) {
1885 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
1886 "Expected OpenMP device compilation.");
1887 return !S.isInOpenMPTargetExecutionDirective();
1888}
1889
1890namespace {
1891/// Status of the function emission on the host/device.
1892enum class FunctionEmissionStatus {
1893 Emitted,
1894 Discarded,
1895 Unknown,
1896};
1897} // anonymous namespace
1898
1899Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
1900 unsigned DiagID,
1901 FunctionDecl *FD) {
1902 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
1903 "Expected OpenMP device compilation.");
1904
1905 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
1906 if (FD) {
1907 FunctionEmissionStatus FES = getEmissionStatus(FD);
1908 switch (FES) {
1909 case FunctionEmissionStatus::Emitted:
1910 Kind = SemaDiagnosticBuilder::K_Immediate;
1911 break;
1912 case FunctionEmissionStatus::Unknown:
1913 // TODO: We should always delay diagnostics here in case a target
1914 // region is in a function we do not emit. However, as the
1915 // current diagnostics are associated with the function containing
1916 // the target region and we do not emit that one, we would miss out
1917 // on diagnostics for the target region itself. We need to anchor
1918 // the diagnostics with the new generated function *or* ensure we
1919 // emit diagnostics associated with the surrounding function.
1920 Kind = isOpenMPDeviceDelayedContext(*this)
1921 ? SemaDiagnosticBuilder::K_Deferred
1922 : SemaDiagnosticBuilder::K_Immediate;
1923 break;
1924 case FunctionEmissionStatus::TemplateDiscarded:
1925 case FunctionEmissionStatus::OMPDiscarded:
1926 Kind = SemaDiagnosticBuilder::K_Nop;
1927 break;
1928 case FunctionEmissionStatus::CUDADiscarded:
1929 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation");
1930 break;
1931 }
1932 }
1933
1934 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
1935}
1936
1937Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
1938 unsigned DiagID,
1939 FunctionDecl *FD) {
1940 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
1941 "Expected OpenMP host compilation.");
1942 FunctionEmissionStatus FES = getEmissionStatus(FD);
1943 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
1944 switch (FES) {
1945 case FunctionEmissionStatus::Emitted:
1946 Kind = SemaDiagnosticBuilder::K_Immediate;
1947 break;
1948 case FunctionEmissionStatus::Unknown:
1949 Kind = SemaDiagnosticBuilder::K_Deferred;
1950 break;
1951 case FunctionEmissionStatus::TemplateDiscarded:
1952 case FunctionEmissionStatus::OMPDiscarded:
1953 case FunctionEmissionStatus::CUDADiscarded:
1954 Kind = SemaDiagnosticBuilder::K_Nop;
1955 break;
1956 }
1957
1958 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
1959}
1960
1961static OpenMPDefaultmapClauseKind
1962getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
1963 if (LO.OpenMP <= 45) {
1964 if (VD->getType().getNonReferenceType()->isScalarType())
1965 return OMPC_DEFAULTMAP_scalar;
1966 return OMPC_DEFAULTMAP_aggregate;
1967 }
1968 if (VD->getType().getNonReferenceType()->isAnyPointerType())
1969 return OMPC_DEFAULTMAP_pointer;
1970 if (VD->getType().getNonReferenceType()->isScalarType())
1971 return OMPC_DEFAULTMAP_scalar;
1972 return OMPC_DEFAULTMAP_aggregate;
1973}
1974
1975bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
1976 unsigned OpenMPCaptureLevel) const {
1977 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1978
1979 ASTContext &Ctx = getASTContext();
1980 bool IsByRef = true;
1981
1982 // Find the directive that is associated with the provided scope.
1983 D = cast<ValueDecl>(D->getCanonicalDecl());
1984 QualType Ty = D->getType();
1985
1986 bool IsVariableUsedInMapClause = false;
1987 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1988 // This table summarizes how a given variable should be passed to the device
1989 // given its type and the clauses where it appears. This table is based on
1990 // the description in OpenMP 4.5 [2.10.4, target Construct] and
1991 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1992 //
1993 // =========================================================================
1994 // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1995 // | |(tofrom:scalar)| | pvt | | | |
1996 // =========================================================================
1997 // | scl | | | | - | | bycopy|
1998 // | scl | | - | x | - | - | bycopy|
1999 // | scl | | x | - | - | - | null |
2000 // | scl | x | | | - | | byref |
2001 // | scl | x | - | x | - | - | bycopy|
2002 // | scl | x | x | - | - | - | null |
2003 // | scl | | - | - | - | x | byref |
2004 // | scl | x | - | - | - | x | byref |
2005 //
2006 // | agg | n.a. | | | - | | byref |
2007 // | agg | n.a. | - | x | - | - | byref |
2008 // | agg | n.a. | x | - | - | - | null |
2009 // | agg | n.a. | - | - | - | x | byref |
2010 // | agg | n.a. | - | - | - | x[] | byref |
2011 //
2012 // | ptr | n.a. | | | - | | bycopy|
2013 // | ptr | n.a. | - | x | - | - | bycopy|
2014 // | ptr | n.a. | x | - | - | - | null |
2015 // | ptr | n.a. | - | - | - | x | byref |
2016 // | ptr | n.a. | - | - | - | x[] | bycopy|
2017 // | ptr | n.a. | - | - | x | | bycopy|
2018 // | ptr | n.a. | - | - | x | x | bycopy|
2019 // | ptr | n.a. | - | - | x | x[] | bycopy|
2020 // =========================================================================
2021 // Legend:
2022 // scl - scalar
2023 // ptr - pointer
2024 // agg - aggregate
2025 // x - applies
2026 // - - invalid in this combination
2027 // [] - mapped with an array section
2028 // byref - should be mapped by reference
2029 // byval - should be mapped by value
2030 // null - initialize a local variable to null on the device
2031 //
2032 // Observations:
2033 // - All scalar declarations that show up in a map clause have to be passed
2034 // by reference, because they may have been mapped in the enclosing data
2035 // environment.
2036 // - If the scalar value does not fit the size of uintptr, it has to be
2037 // passed by reference, regardless the result in the table above.
2038 // - For pointers mapped by value that have either an implicit map or an
2039 // array section, the runtime library may pass the NULL value to the
2040 // device instead of the value passed to it by the compiler.
2041
2042 if (Ty->isReferenceType())
2043 Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2044
2045 // Locate map clauses and see if the variable being captured is referred to
2046 // in any of those clauses. Here we only care about variables, not fields,
2047 // because fields are part of aggregates.
2048 bool IsVariableAssociatedWithSection = false;
2049
2050 DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2051 D, Level,
2052 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
2053 OMPClauseMappableExprCommon::MappableExprComponentListRef
2054 MapExprComponents,
2055 OpenMPClauseKind WhereFoundClauseKind) {
2056 // Only the map clause information influences how a variable is
2057 // captured. E.g. is_device_ptr does not require changing the default
2058 // behavior.
2059 if (WhereFoundClauseKind != OMPC_map)
2060 return false;
2061
2062 auto EI = MapExprComponents.rbegin();
2063 auto EE = MapExprComponents.rend();
2064
2065 assert(EI != EE && "Invalid map expression!");
2066
2067 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2068 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2069
2070 ++EI;
2071 if (EI == EE)
2072 return false;
2073
2074 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
2075 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
2076 isa<MemberExpr>(EI->getAssociatedExpression()) ||
2077 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) {
2078 IsVariableAssociatedWithSection = true;
2079 // There is nothing more we need to know about this variable.
2080 return true;
2081 }
2082
2083 // Keep looking for more map info.
2084 return false;
2085 });
2086
2087 if (IsVariableUsedInMapClause) {
2088 // If variable is identified in a map clause it is always captured by
2089 // reference except if it is a pointer that is dereferenced somehow.
2090 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2091 } else {
2092 // By default, all the data that has a scalar type is mapped by copy
2093 // (except for reduction variables).
2094 // Defaultmap scalar is mutual exclusive to defaultmap pointer
2095 IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2096 !Ty->isAnyPointerType()) ||
2097 !Ty->isScalarType() ||
2098 DSAStack->isDefaultmapCapturedByRef(
2099 Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2100 DSAStack->hasExplicitDSA(
2101 D,
2102 [](OpenMPClauseKind K, bool AppliedToPointee) {
2103 return K == OMPC_reduction && !AppliedToPointee;
2104 },
2105 Level);
2106 }
2107 }
2108
2109 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2110 IsByRef =
2111 ((IsVariableUsedInMapClause &&
2112 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2113 OMPD_target) ||
2114 !(DSAStack->hasExplicitDSA(
2115 D,
2116 [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
2117 return K == OMPC_firstprivate ||
2118 (K == OMPC_reduction && AppliedToPointee);
2119 },
2120 Level, /*NotLastprivate=*/true) ||
2121 DSAStack->isUsesAllocatorsDecl(Level, D))) &&
2122 // If the variable is artificial and must be captured by value - try to
2123 // capture by value.
2124 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2125 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2126 // If the variable is implicitly firstprivate and scalar - capture by
2127 // copy
2128 !(DSAStack->getDefaultDSA() == DSA_firstprivate &&
2129 !DSAStack->hasExplicitDSA(
2130 D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
2131 Level) &&
2132 !DSAStack->isLoopControlVariable(D, Level).first);
2133 }
2134
2135 // When passing data by copy, we need to make sure it fits the uintptr size
2136 // and alignment, because the runtime library only deals with uintptr types.
2137 // If it does not fit the uintptr size, we need to pass the data by reference
2138 // instead.
2139 if (!IsByRef &&
2140 (Ctx.getTypeSizeInChars(Ty) >
2141 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2142 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2143 IsByRef = true;
2144 }
2145
2146 return IsByRef;
2147}
2148
2149unsigned Sema::getOpenMPNestingLevel() const {
2150 assert(getLangOpts().OpenMP);
2151 return DSAStack->getNestingLevel();
2152}
2153
2154bool Sema::isInOpenMPTargetExecutionDirective() const {
2155 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
2156 !DSAStack->isClauseParsingMode()) ||
2157 DSAStack->hasDirective(
2158 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2159 SourceLocation) -> bool {
2160 return isOpenMPTargetExecutionDirective(K);
2161 },
2162 false);
2163}
2164
2165VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2166 unsigned StopAt) {
2167 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2168 D = getCanonicalDecl(D);
2169
2170 auto *VD = dyn_cast<VarDecl>(D);
2171 // Do not capture constexpr variables.
2172 if (VD && VD->isConstexpr())
2173 return nullptr;
2174
2175 // If we want to determine whether the variable should be captured from the
2176 // perspective of the current capturing scope, and we've already left all the
2177 // capturing scopes of the top directive on the stack, check from the
2178 // perspective of its parent directive (if any) instead.
2179 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2180 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete());
2181
2182 // If we are attempting to capture a global variable in a directive with
2183 // 'target' we return true so that this global is also mapped to the device.
2184 //
2185 if (VD && !VD->hasLocalStorage() &&
2186 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2187 if (isInOpenMPDeclareTargetContext()) {
2188 // Try to mark variable as declare target if it is used in capturing
2189 // regions.
2190 if (LangOpts.OpenMP <= 45 &&
2191 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2192 checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2193 return nullptr;
2194 }
2195 if (isInOpenMPTargetExecutionDirective()) {
2196 // If the declaration is enclosed in a 'declare target' directive,
2197 // then it should not be captured.
2198 //
2199 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2200 return nullptr;
2201 CapturedRegionScopeInfo *CSI = nullptr;
2202 for (FunctionScopeInfo *FSI : llvm::drop_begin(
2203 llvm::reverse(FunctionScopes),
2204 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2205 if (!isa<CapturingScopeInfo>(FSI))
2206 return nullptr;
2207 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2208 if (RSI->CapRegionKind == CR_OpenMP) {
2209 CSI = RSI;
2210 break;
2211 }
2212 }
2213 assert(CSI && "Failed to find CapturedRegionScopeInfo");
2214 SmallVector<OpenMPDirectiveKind, 4> Regions;
2215 getOpenMPCaptureRegions(Regions,
2216 DSAStack->getDirective(CSI->OpenMPLevel));
2217 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2218 return VD;
2219 }
2220 }
2221
2222 if (CheckScopeInfo) {
2223 bool OpenMPFound = false;
2224 for (unsigned I = StopAt + 1; I > 0; --I) {
2225 FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2226 if(!isa<CapturingScopeInfo>(FSI))
2227 return nullptr;
2228 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2229 if (RSI->CapRegionKind == CR_OpenMP) {
2230 OpenMPFound = true;
2231 break;
2232 }
2233 }
2234 if (!OpenMPFound)
2235 return nullptr;
2236 }
2237
2238 if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2239 (!DSAStack->isClauseParsingMode() ||
2240 DSAStack->getParentDirective() != OMPD_unknown)) {
2241 auto &&Info = DSAStack->isLoopControlVariable(D);
2242 if (Info.first ||
2243 (VD && VD->hasLocalStorage() &&
2244 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
2245 (VD && DSAStack->isForceVarCapturing()))
2246 return VD ? VD : Info.second;
2247 DSAStackTy::DSAVarData DVarTop =
2248 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2249 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
2250 (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2251 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2252 // Threadprivate variables must not be captured.
2253 if (isOpenMPThreadPrivate(DVarTop.CKind))
2254 return nullptr;
2255 // The variable is not private or it is the variable in the directive with
2256 // default(none) clause and not used in any clause.
2257 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2258 D,
2259 [](OpenMPClauseKind C, bool AppliedToPointee) {
2260 return isOpenMPPrivate(C) && !AppliedToPointee;
2261 },
2262 [](OpenMPDirectiveKind) { return true; },
2263 DSAStack->isClauseParsingMode());
2264 // Global shared must not be captured.
2265 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2266 ((DSAStack->getDefaultDSA() != DSA_none &&
2267 DSAStack->getDefaultDSA() != DSA_firstprivate) ||
2268 DVarTop.CKind == OMPC_shared))
2269 return nullptr;
2270 if (DVarPrivate.CKind != OMPC_unknown ||
2271 (VD && (DSAStack->getDefaultDSA() == DSA_none ||
2272 DSAStack->getDefaultDSA() == DSA_firstprivate)))
2273 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2274 }
2275 return nullptr;
2276}
2277
2278void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2279 unsigned Level) const {
2280 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2281}
2282
2283void Sema::startOpenMPLoop() {
2284 assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2285 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
2286 DSAStack->loopInit();
2287}
2288
2289void Sema::startOpenMPCXXRangeFor() {
2290 assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2291 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2292 DSAStack->resetPossibleLoopCounter();
2293 DSAStack->loopStart();
2294 }
2295}
2296
2297OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2298 unsigned CapLevel) const {
2299 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2300 if (DSAStack->hasExplicitDirective(
2301 [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); },
2302 Level)) {
2303 bool IsTriviallyCopyable =
2304 D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
2305 !D->getType()
2306 .getNonReferenceType()
2307 .getCanonicalType()
2308 ->getAsCXXRecordDecl();
2309 OpenMPDirectiveKind DKind = DSAStack->getDirective(Level);
2310 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2311 getOpenMPCaptureRegions(CaptureRegions, DKind);
2312 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2313 (IsTriviallyCopyable ||
2314 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2315 if (DSAStack->hasExplicitDSA(
2316 D,
2317 [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
2318 Level, /*NotLastprivate=*/true))
2319 return OMPC_firstprivate;
2320 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2321 if (DVar.CKind != OMPC_shared &&
2322 !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2323 DSAStack->addImplicitTaskFirstprivate(Level, D);
2324 return OMPC_firstprivate;
2325 }
2326 }
2327 }
2328 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2329 if (DSAStack->getAssociatedLoops() > 0 &&
2330 !DSAStack->isLoopStarted()) {
2331 DSAStack->resetPossibleLoopCounter(D);
2332 DSAStack->loopStart();
2333 return OMPC_private;
2334 }
2335 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2336 DSAStack->isLoopControlVariable(D).first) &&
2337 !DSAStack->hasExplicitDSA(
2338 D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
2339 Level) &&
2340 !isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
2341 return OMPC_private;
2342 }
2343 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2344 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2345 DSAStack->isForceVarCapturing() &&
2346 !DSAStack->hasExplicitDSA(
2347 D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
2348 Level))
2349 return OMPC_private;
2350 }
2351 // User-defined allocators are private since they must be defined in the
2352 // context of target region.
2353 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2354 DSAStack->isUsesAllocatorsDecl(Level, D).getValueOr(
2355 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2356 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2357 return OMPC_private;
2358 return (DSAStack->hasExplicitDSA(
2359 D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
2360 Level) ||
2361 (DSAStack->isClauseParsingMode() &&
2362 DSAStack->getClauseParsingMode() == OMPC_private) ||
2363 // Consider taskgroup reduction descriptor variable a private
2364 // to avoid possible capture in the region.
2365 (DSAStack->hasExplicitDirective(
2366 [](OpenMPDirectiveKind K) {
2367 return K == OMPD_taskgroup ||
2368 ((isOpenMPParallelDirective(K) ||
2369 isOpenMPWorksharingDirective(K)) &&
2370 !isOpenMPSimdDirective(K));
2371 },
2372 Level) &&
2373 DSAStack->isTaskgroupReductionRef(D, Level)))
2374 ? OMPC_private
2375 : OMPC_unknown;
2376}
2377
2378void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2379 unsigned Level) {
2380 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2381 D = getCanonicalDecl(D);
2382 OpenMPClauseKind OMPC = OMPC_unknown;
2383 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
2384 const unsigned NewLevel = I - 1;
2385 if (DSAStack->hasExplicitDSA(
2386 D,
2387 [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2388 if (isOpenMPPrivate(K) && !AppliedToPointee) {
2389 OMPC = K;
2390 return true;
2391 }
2392 return false;
2393 },
2394 NewLevel))
2395 break;
2396 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2397 D, NewLevel,
2398 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2399 OpenMPClauseKind) { return true; })) {
2400 OMPC = OMPC_map;
2401 break;
2402 }
2403 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2404 NewLevel)) {
2405 OMPC = OMPC_map;
2406 if (DSAStack->mustBeFirstprivateAtLevel(
2407 NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2408 OMPC = OMPC_firstprivate;
2409 break;
2410 }
2411 }
2412 if (OMPC != OMPC_unknown)
2413 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2414}
2415
2416bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2417 unsigned CaptureLevel) const {
2418 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2419 // Return true if the current level is no longer enclosed in a target region.
2420
2421 SmallVector<OpenMPDirectiveKind, 4> Regions;
2422 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
2423 const auto *VD = dyn_cast<VarDecl>(D);
2424 return VD && !VD->hasLocalStorage() &&
2425 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2426 Level) &&
2427 Regions[CaptureLevel] != OMPD_task;
2428}
2429
2430bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2431 unsigned CaptureLevel) const {
2432 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2433 // Return true if the current level is no longer enclosed in a target region.
2434
2435 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2436 if (!VD->hasLocalStorage()) {
2437 if (isInOpenMPTargetExecutionDirective())
2438 return true;
2439 DSAStackTy::DSAVarData TopDVar =
2440 DSAStack->getTopDSA(D, /*FromParent=*/false);
2441 unsigned NumLevels =
2442 getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2443 if (Level == 0)
2444 return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared;
2445 do {
2446 --Level;
2447 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2448 if (DVar.CKind != OMPC_shared)
2449 return true;
2450 } while (Level > 0);
2451 }
2452 }
2453 return true;
2454}
2455
2456void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
2457
2458void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2459 OMPTraitInfo &TI) {
2460 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2461}
2462
2463void Sema::ActOnOpenMPEndDeclareVariant() {
2464 assert(isInOpenMPDeclareVariantScope() &&
2465 "Not in OpenMP declare variant scope!");
2466
2467 OMPDeclareVariantScopes.pop_back();
2468}
2469
2470void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2471 const FunctionDecl *Callee,
2472 SourceLocation Loc) {
2473 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.");
2474 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2475 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2476 // Ignore host functions during device analyzis.
2477 if (LangOpts.OpenMPIsDevice && DevTy &&
2478 *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2479 return;
2480 // Ignore nohost functions during host analyzis.
2481 if (!LangOpts.OpenMPIsDevice && DevTy &&
2482 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2483 return;
2484 const FunctionDecl *FD = Callee->getMostRecentDecl();
2485 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2486 if (LangOpts.OpenMPIsDevice && DevTy &&
2487 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2488 // Diagnose host function called during device codegen.
2489 StringRef HostDevTy =
2490 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2491 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2492 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2493 diag::note_omp_marked_device_type_here)
2494 << HostDevTy;
2495 return;
2496 }
2497 if (!LangOpts.OpenMPIsDevice && DevTy &&
2498 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2499 // Diagnose nohost function called during host codegen.
2500 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2501 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2502 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2503 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2504 diag::note_omp_marked_device_type_here)
2505 << NoHostDevTy;
2506 }
2507}
2508
2509void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2510 const DeclarationNameInfo &DirName,
2511 Scope *CurScope, SourceLocation Loc) {
2512 DSAStack->push(DKind, DirName, CurScope, Loc);
2513 PushExpressionEvaluationContext(
2514 ExpressionEvaluationContext::PotentiallyEvaluated);
2515}
2516
2517void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2518 DSAStack->setClauseParsingMode(K);
2519}
2520
2521void Sema::EndOpenMPClause() {
2522 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
2523}
2524
2525static std::pair<ValueDecl *, bool>
2526getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2527 SourceRange &ERange, bool AllowArraySection = false);
2528
2529/// Check consistency of the reduction clauses.
2530static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2531 ArrayRef<OMPClause *> Clauses) {
2532 bool InscanFound = false;
2533 SourceLocation InscanLoc;
2534 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2535 // A reduction clause without the inscan reduction-modifier may not appear on
2536 // a construct on which a reduction clause with the inscan reduction-modifier
2537 // appears.
2538 for (OMPClause *C : Clauses) {
2539 if (C->getClauseKind() != OMPC_reduction)
2540 continue;
2541 auto *RC = cast<OMPReductionClause>(C);
2542 if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2543 InscanFound = true;
2544 InscanLoc = RC->getModifierLoc();
2545 continue;
2546 }
2547 if (RC->getModifier() == OMPC_REDUCTION_task) {
2548 // OpenMP 5.0, 2.19.5.4 reduction Clause.
2549 // A reduction clause with the task reduction-modifier may only appear on
2550 // a parallel construct, a worksharing construct or a combined or
2551 // composite construct for which any of the aforementioned constructs is a
2552 // constituent construct and simd or loop are not constituent constructs.
2553 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2554 if (!(isOpenMPParallelDirective(CurDir) ||
2555 isOpenMPWorksharingDirective(CurDir)) ||
2556 isOpenMPSimdDirective(CurDir))
2557 S.Diag(RC->getModifierLoc(),
2558 diag::err_omp_reduction_task_not_parallel_or_worksharing);
2559 continue;
2560 }
2561 }
2562 if (InscanFound) {
2563 for (OMPClause *C : Clauses) {
2564 if (C->getClauseKind() != OMPC_reduction)
2565 continue;
2566 auto *RC = cast<OMPReductionClause>(C);
2567 if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2568 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2569 ? RC->getBeginLoc()
2570 : RC->getModifierLoc(),
2571 diag::err_omp_inscan_reduction_expected);
2572 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2573 continue;
2574 }
2575 for (Expr *Ref : RC->varlists()) {
2576 assert(Ref && "NULL expr in OpenMP nontemporal clause.");
2577 SourceLocation ELoc;
2578 SourceRange ERange;
2579 Expr *SimpleRefExpr = Ref;
2580 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2581 /*AllowArraySection=*/true);
2582 ValueDecl *D = Res.first;
2583 if (!D)
2584 continue;
2585 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2586 S.Diag(Ref->getExprLoc(),
2587 diag::err_omp_reduction_not_inclusive_exclusive)
2588 << Ref->getSourceRange();
2589 }
2590 }
2591 }
2592 }
2593}
2594
2595static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2596 ArrayRef<OMPClause *> Clauses);
2597static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2598 bool WithInit);
2599
2600static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2601 const ValueDecl *D,
2602 const DSAStackTy::DSAVarData &DVar,
2603 bool IsLoopIterVar = false);
2604
2605void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2606 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2607 // A variable of class type (or array thereof) that appears in a lastprivate
2608 // clause requires an accessible, unambiguous default constructor for the
2609 // class type, unless the list item is also specified in a firstprivate
2610 // clause.
2611 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2612 for (OMPClause *C : D->clauses()) {
2613 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2614 SmallVector<Expr *, 8> PrivateCopies;
2615 for (Expr *DE : Clause->varlists()) {
2616 if (DE->isValueDependent() || DE->isTypeDependent()) {
2617 PrivateCopies.push_back(nullptr);
2618 continue;
2619 }
2620 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2621 auto *VD = cast<VarDecl>(DRE->getDecl());
2622 QualType Type = VD->getType().getNonReferenceType();
2623 const DSAStackTy::DSAVarData DVar =
2624 DSAStack->getTopDSA(VD, /*FromParent=*/false);
2625 if (DVar.CKind == OMPC_lastprivate) {
2626 // Generate helper private variable and initialize it with the
2627 // default value. The address of the original variable is replaced
2628 // by the address of the new private variable in CodeGen. This new
2629 // variable is not added to IdResolver, so the code in the OpenMP
2630 // region uses original variable for proper diagnostics.
2631 VarDecl *VDPrivate = buildVarDecl(
2632 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2633 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2634 ActOnUninitializedDecl(VDPrivate);
2635 if (VDPrivate->isInvalidDecl()) {
2636 PrivateCopies.push_back(nullptr);
2637 continue;
2638 }
2639 PrivateCopies.push_back(buildDeclRefExpr(
2640 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2641 } else {
2642 // The variable is also a firstprivate, so initialization sequence
2643 // for private copy is generated already.
2644 PrivateCopies.push_back(nullptr);
2645 }
2646 }
2647 Clause->setPrivateCopies(PrivateCopies);
2648 continue;
2649 }
2650 // Finalize nontemporal clause by handling private copies, if any.
2651 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2652 SmallVector<Expr *, 8> PrivateRefs;
2653 for (Expr *RefExpr : Clause->varlists()) {
2654 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
2655 SourceLocation ELoc;
2656 SourceRange ERange;
2657 Expr *SimpleRefExpr = RefExpr;
2658 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2659 if (Res.second)
2660 // It will be analyzed later.
2661 PrivateRefs.push_back(RefExpr);
2662 ValueDecl *D = Res.first;
2663 if (!D)
2664 continue;
2665
2666 const DSAStackTy::DSAVarData DVar =
2667 DSAStack->getTopDSA(D, /*FromParent=*/false);
2668 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2669 : SimpleRefExpr);
2670 }
2671 Clause->setPrivateRefs(PrivateRefs);
2672 continue;
2673 }
2674 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2675 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2676 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2677 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2678 if (!DRE)
2679 continue;
2680 ValueDecl *VD = DRE->getDecl();
2681 if (!VD || !isa<VarDecl>(VD))
2682 continue;
2683 DSAStackTy::DSAVarData DVar =
2684 DSAStack->getTopDSA(VD, /*FromParent=*/false);
2685 // OpenMP [2.12.5, target Construct]
2686 // Memory allocators that appear in a uses_allocators clause cannot
2687 // appear in other data-sharing attribute clauses or data-mapping
2688 // attribute clauses in the same construct.
2689 Expr *MapExpr = nullptr;
2690 if (DVar.RefExpr ||
2691 DSAStack->checkMappableExprComponentListsForDecl(
2692 VD, /*CurrentRegionOnly=*/true,
2693 [VD, &MapExpr](
2694 OMPClauseMappableExprCommon::MappableExprComponentListRef
2695 MapExprComponents,
2696 OpenMPClauseKind C) {
2697 auto MI = MapExprComponents.rbegin();
2698 auto ME = MapExprComponents.rend();
2699 if (MI != ME &&
2700 MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2701 VD->getCanonicalDecl()) {
2702 MapExpr = MI->getAssociatedExpression();
2703 return true;
2704 }
2705 return false;
2706 })) {
2707 Diag(D.Allocator->getExprLoc(),
2708 diag::err_omp_allocator_used_in_clauses)
2709 << D.Allocator->getSourceRange();
2710 if (DVar.RefExpr)
2711 reportOriginalDsa(*this, DSAStack, VD, DVar);
2712 else
2713 Diag(MapExpr->getExprLoc(), diag::note_used_here)
2714 << MapExpr->getSourceRange();
2715 }
2716 }
2717 continue;
2718 }
2719 }
2720 // Check allocate clauses.
2721 if (!CurContext->isDependentContext())
2722 checkAllocateClauses(*this, DSAStack, D->clauses());
2723 checkReductionClauses(*this, DSAStack, D->clauses());
2724 }
2725
2726 DSAStack->pop();
2727 DiscardCleanupsInEvaluationContext();
2728 PopExpressionEvaluationContext();
2729}
2730
2731static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2732 Expr *NumIterations, Sema &SemaRef,
2733 Scope *S, DSAStackTy *Stack);
2734
2735namespace {
2736
2737class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2738private:
2739 Sema &SemaRef;
2740
2741public:
2742 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
2743 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2744 NamedDecl *ND = Candidate.getCorrectionDecl();
2745 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2746 return VD->hasGlobalStorage() &&
2747 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2748 SemaRef.getCurScope());
2749 }
2750 return false;
2751 }
2752
2753 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2754 return std::make_unique<VarDeclFilterCCC>(*this);
2755 }
2756
2757};
2758
2759class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2760private:
2761 Sema &SemaRef;
2762
2763public:
2764 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
2765 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2766 NamedDecl *ND = Candidate.getCorrectionDecl();
2767 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2768 isa<FunctionDecl>(ND))) {
2769 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2770 SemaRef.getCurScope());
2771 }
2772 return false;
2773 }
2774
2775 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2776 return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2777 }
2778};
2779
2780} // namespace
2781
2782ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2783 CXXScopeSpec &ScopeSpec,
2784 const DeclarationNameInfo &Id,
2785 OpenMPDirectiveKind Kind) {
2786 LookupResult Lookup(*this, Id, LookupOrdinaryName);
2787 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2788
2789 if (Lookup.isAmbiguous())
2790 return ExprError();
2791
2792 VarDecl *VD;
2793 if (!Lookup.isSingleResult()) {
2794 VarDeclFilterCCC CCC(*this);
2795 if (TypoCorrection Corrected =
2796 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2797 CTK_ErrorRecovery)) {
2798 diagnoseTypo(Corrected,
2799 PDiag(Lookup.empty()
2800 ? diag::err_undeclared_var_use_suggest
2801 : diag::err_omp_expected_var_arg_suggest)
2802 << Id.getName());
2803 VD = Corrected.getCorrectionDeclAs<VarDecl>();
2804 } else {
2805 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2806 : diag::err_omp_expected_var_arg)
2807 << Id.getName();
2808 return ExprError();
2809 }
2810 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2811 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2812 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2813 return ExprError();
2814 }
2815 Lookup.suppressDiagnostics();
2816
2817 // OpenMP [2.9.2, Syntax, C/C++]
2818 // Variables must be file-scope, namespace-scope, or static block-scope.
2819 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
2820 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
2821 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
2822 bool IsDecl =
2823 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2824 Diag(VD->getLocation(),
2825 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2826 << VD;
2827 return ExprError();
2828 }
2829
2830 VarDecl *CanonicalVD = VD->getCanonicalDecl();
2831 NamedDecl *ND = CanonicalVD;
2832 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2833 // A threadprivate directive for file-scope variables must appear outside
2834 // any definition or declaration.
2835 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2836 !getCurLexicalContext()->isTranslationUnit()) {
2837 Diag(Id.getLoc(), diag::err_omp_var_scope)
2838 << getOpenMPDirectiveName(Kind) << VD;
2839 bool IsDecl =
2840 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2841 Diag(VD->getLocation(),
2842 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2843 << VD;
2844 return ExprError();
2845 }
2846 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2847 // A threadprivate directive for static class member variables must appear
2848 // in the class definition, in the same scope in which the member
2849 // variables are declared.
2850 if (CanonicalVD->isStaticDataMember() &&
2851 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
2852 Diag(Id.getLoc(), diag::err_omp_var_scope)
2853 << getOpenMPDirectiveName(Kind) << VD;
2854 bool IsDecl =
2855 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2856 Diag(VD->getLocation(),
2857 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2858 << VD;
2859 return ExprError();
2860 }
2861 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
2862 // A threadprivate directive for namespace-scope variables must appear
2863 // outside any definition or declaration other than the namespace
2864 // definition itself.
2865 if (CanonicalVD->getDeclContext()->isNamespace() &&
2866 (!getCurLexicalContext()->isFileContext() ||
2867 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2868 Diag(Id.getLoc(), diag::err_omp_var_scope)
2869 << getOpenMPDirectiveName(Kind) << VD;
2870 bool IsDecl =
2871 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2872 Diag(VD->getLocation(),
2873 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2874 << VD;
2875 return ExprError();
2876 }
2877 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2878 // A threadprivate directive for static block-scope variables must appear
2879 // in the scope of the variable and not in a nested scope.
2880 if (CanonicalVD->isLocalVarDecl() && CurScope &&
2881 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2882 Diag(Id.getLoc(), diag::err_omp_var_scope)
2883 << getOpenMPDirectiveName(Kind) << VD;
2884 bool IsDecl =
2885 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2886 Diag(VD->getLocation(),
2887 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2888 << VD;
2889 return ExprError();
2890 }
2891
2892 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2893 // A threadprivate directive must lexically precede all references to any
2894 // of the variables in its list.
2895 if (Kind == OMPD_threadprivate && VD->isUsed() &&
2896 !DSAStack->isThreadPrivate(VD)) {
2897 Diag(Id.getLoc(), diag::err_omp_var_used)
2898 << getOpenMPDirectiveName(Kind) << VD;
2899 return ExprError();
2900 }
2901
2902 QualType ExprType = VD->getType().getNonReferenceType();
2903 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
2904 SourceLocation(), VD,
2905 /*RefersToEnclosingVariableOrCapture=*/false,
2906 Id.getLoc(), ExprType, VK_LValue);
2907}
2908
2909Sema::DeclGroupPtrTy
2910Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
2911 ArrayRef<Expr *> VarList) {
2912 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
2913 CurContext->addDecl(D);
2914 return DeclGroupPtrTy::make(DeclGroupRef(D));
2915 }
2916 return nullptr;
2917}
2918
2919namespace {
2920class LocalVarRefChecker final
2921 : public ConstStmtVisitor<LocalVarRefChecker, bool> {
2922 Sema &SemaRef;
2923
2924public:
2925 bool VisitDeclRefExpr(const DeclRefExpr *E) {
2926 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2927 if (VD->hasLocalStorage()) {
2928 SemaRef.Diag(E->getBeginLoc(),
2929 diag::err_omp_local_var_in_threadprivate_init)
2930 << E->getSourceRange();
2931 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2932 << VD << VD->getSourceRange();
2933 return true;
2934 }
2935 }
2936 return false;
2937 }
2938 bool VisitStmt(const Stmt *S) {
2939 for (const Stmt *Child : S->children()) {
2940 if (Child && Visit(Child))
2941 return true;
2942 }
2943 return false;
2944 }
2945 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2946};
2947} // namespace
2948
2949OMPThreadPrivateDecl *
2950Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
2951 SmallVector<Expr *, 8> Vars;
2952 for (Expr *RefExpr : VarList) {
2953 auto *DE = cast<DeclRefExpr>(RefExpr);
2954 auto *VD = cast<VarDecl>(DE->getDecl());
2955 SourceLocation ILoc = DE->getExprLoc();
2956
2957 // Mark variable as used.
2958 VD->setReferenced();
2959 VD->markUsed(Context);
2960
2961 QualType QType = VD->getType();
2962 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2963 // It will be analyzed later.
2964 Vars.push_back(DE);
2965 continue;
2966 }
2967
2968 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2969 // A threadprivate variable must not have an incomplete type.
2970 if (RequireCompleteType(ILoc, VD->getType(),
2971 diag::err_omp_threadprivate_incomplete_type)) {
2972 continue;
2973 }
2974
2975 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2976 // A threadprivate variable must not have a reference type.
2977 if (VD->getType()->isReferenceType()) {
2978 Diag(ILoc, diag::err_omp_ref_type_arg)
2979 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2980 bool IsDecl =
2981 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2982 Diag(VD->getLocation(),
2983 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2984 << VD;
2985 continue;
2986 }
2987
2988 // Check if this is a TLS variable. If TLS is not being supported, produce
2989 // the corresponding diagnostic.
2990 if ((VD->getTLSKind() != VarDecl::TLS_None &&
2991 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
2992 getLangOpts().OpenMPUseTLS &&
2993 getASTContext().getTargetInfo().isTLSSupported())) ||
2994 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2995 !VD->isLocalVarDecl())) {
2996 Diag(ILoc, diag::err_omp_var_thread_local)
2997 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
2998 bool IsDecl =
2999 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3000 Diag(VD->getLocation(),
3001 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3002 << VD;
3003 continue;
3004 }
3005
3006 // Check if initial value of threadprivate variable reference variable with
3007 // local storage (it is not supported by runtime).
3008 if (const Expr *Init = VD->getAnyInitializer()) {
3009 LocalVarRefChecker Checker(*this);
3010 if (Checker.Visit(Init))
3011 continue;
3012 }
3013
3014 Vars.push_back(RefExpr);
3015 DSAStack->addDSA(VD, DE, OMPC_threadprivate);
3016 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3017 Context, SourceRange(Loc, Loc)));
3018 if (ASTMutationListener *ML = Context.getASTMutationListener())
3019 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3020 }
3021 OMPThreadPrivateDecl *D = nullptr;
3022 if (!Vars.empty()) {
3023 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
3024 Vars);
3025 D->setAccess(AS_public);
3026 }
3027 return D;
3028}
3029
3030static OMPAllocateDeclAttr::AllocatorTypeTy
3031getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3032 if (!Allocator)
3033 return OMPAllocateDeclAttr::OMPNullMemAlloc;
3034 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3035 Allocator->isInstantiationDependent() ||
3036 Allocator->containsUnexpandedParameterPack())
3037 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3038 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3039 const Expr *AE = Allocator->IgnoreParenImpCasts();
3040 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3041 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3042 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3043 llvm::FoldingSetNodeID AEId, DAEId;
3044 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3045 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
3046 if (AEId == DAEId) {
3047 AllocatorKindRes = AllocatorKind;
3048 break;
3049 }
3050 }
3051 return AllocatorKindRes;
3052}
3053
3054static bool checkPreviousOMPAllocateAttribute(
3055 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3056 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3057 if (!VD->hasAttr<OMPAllocateDeclAttr>())
3058 return false;
3059 const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3060 Expr *PrevAllocator = A->getAllocator();
3061 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3062 getAllocatorKind(S, Stack, PrevAllocator);
3063 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3064 if (AllocatorsMatch &&
3065 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3066 Allocator && PrevAllocator) {
3067 const Expr *AE = Allocator->IgnoreParenImpCasts();
3068 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3069 llvm::FoldingSetNodeID AEId, PAEId;
3070 AE->Profile(AEId, S.Context, /*Canonical=*/true);
3071 PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3072 AllocatorsMatch = AEId == PAEId;
3073 }
3074 if (!AllocatorsMatch) {
3075 SmallString<256> AllocatorBuffer;
3076 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3077 if (Allocator)
3078 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3079 SmallString<256> PrevAllocatorBuffer;
3080 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3081 if (PrevAllocator)
3082 PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3083 S.getPrintingPolicy());
3084
3085 SourceLocation AllocatorLoc =
3086 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3087 SourceRange AllocatorRange =
3088 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3089 SourceLocation PrevAllocatorLoc =
3090 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3091 SourceRange PrevAllocatorRange =
3092 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3093 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3094 << (Allocator ? 1 : 0) << AllocatorStream.str()
3095 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3096 << AllocatorRange;
3097 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3098 << PrevAllocatorRange;
3099 return true;
3100 }
3101 return false;
3102}
3103
3104static void
3105applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3106 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3107 Expr *Allocator, SourceRange SR) {
3108 if (VD->hasAttr<OMPAllocateDeclAttr>())
3109 return;
3110 if (Allocator &&
3111 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3112 Allocator->isInstantiationDependent() ||
3113 Allocator->containsUnexpandedParameterPack()))
3114 return;
3115 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3116 Allocator, SR);
3117 VD->addAttr(A);
3118 if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3119 ML->DeclarationMarkedOpenMPAllocate(VD, A);
3120}
3121
3122Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
3123 SourceLocation Loc, ArrayRef<Expr *> VarList,
3124 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
3125 assert(Clauses.size() <= 1 && "Expected at most one clause.");
3126 Expr *Allocator = nullptr;
3127 if (Clauses.empty()) {
3128 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3129 // allocate directives that appear in a target region must specify an
3130 // allocator clause unless a requires directive with the dynamic_allocators
3131 // clause is present in the same compilation unit.
3132 if (LangOpts.OpenMPIsDevice &&
3133 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3134 targetDiag(Loc, diag::err_expected_allocator_clause);
3135 } else {
3136 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
3137 }
3138 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3139 getAllocatorKind(*this, DSAStack, Allocator);
3140 SmallVector<Expr *, 8> Vars;
3141 for (Expr *RefExpr : VarList) {
3142 auto *DE = cast<DeclRefExpr>(RefExpr);
3143 auto *VD = cast<VarDecl>(DE->getDecl());
3144
3145 // Check if this is a TLS variable or global register.
3146 if (VD->getTLSKind() != VarDecl::TLS_None ||
3147 VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3148 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3149 !VD->isLocalVarDecl()))
3150 continue;
3151
3152 // If the used several times in the allocate directive, the same allocator
3153 // must be used.
3154 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD,
3155 AllocatorKind, Allocator))
3156 continue;
3157
3158 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3159 // If a list item has a static storage type, the allocator expression in the
3160 // allocator clause must be a constant expression that evaluates to one of
3161 // the predefined memory allocator values.
3162 if (Allocator && VD->hasGlobalStorage()) {
3163 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3164 Diag(Allocator->getExprLoc(),
3165 diag::err_omp_expected_predefined_allocator)
3166 << Allocator->getSourceRange();
3167 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3168 VarDecl::DeclarationOnly;
3169 Diag(VD->getLocation(),
3170 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3171 << VD;
3172 continue;
3173 }
3174 }
3175
3176 Vars.push_back(RefExpr);
3177 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator,
3178 DE->getSourceRange());
3179 }
3180 if (Vars.empty())
3181 return nullptr;
3182 if (!Owner)
3183 Owner = getCurLexicalContext();
3184 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3185 D->setAccess(AS_public);
3186 Owner->addDecl(D);
3187 return DeclGroupPtrTy::make(DeclGroupRef(D));
3188}
3189
3190Sema::DeclGroupPtrTy
3191Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3192 ArrayRef<OMPClause *> ClauseList) {
3193 OMPRequiresDecl *D = nullptr;
3194 if (!CurContext->isFileContext()) {
3195 Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3196 } else {
3197 D = CheckOMPRequiresDecl(Loc, ClauseList);
3198 if (D) {
3199 CurContext->addDecl(D);
3200 DSAStack->addRequiresDecl(D);
3201 }
3202 }
3203 return DeclGroupPtrTy::make(DeclGroupRef(D));
3204}
3205
3206void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc,
3207 OpenMPDirectiveKind DKind,
3208 ArrayRef<StringRef> Assumptions,
3209 bool SkippedClauses) {
3210 if (!SkippedClauses && Assumptions.empty())
3211 Diag(Loc, diag::err_omp_no_clause_for_directive)
3212 << llvm::omp::getAllAssumeClauseOptions()
3213 << llvm::omp::getOpenMPDirectiveName(DKind);
3214
3215 auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc);
3216 if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3217 OMPAssumeScoped.push_back(AA);
3218 return;
3219 }
3220
3221 // Global assumes without assumption clauses are ignored.
3222 if (Assumptions.empty())
3223 return;
3224
3225 assert(DKind == llvm::omp::Directive::OMPD_assumes &&
3226 "Unexpected omp assumption directive!");
3227 OMPAssumeGlobal.push_back(AA);
3228
3229 // The OMPAssumeGlobal scope above will take care of new declarations but
3230 // we also want to apply the assumption to existing ones, e.g., to
3231 // declarations in included headers. To this end, we traverse all existing
3232 // declaration contexts and annotate function declarations here.
3233 SmallVector<DeclContext *, 8> DeclContexts;
3234 auto *Ctx = CurContext;
3235 while (Ctx->getLexicalParent())
3236 Ctx = Ctx->getLexicalParent();
3237 DeclContexts.push_back(Ctx);
3238 while (!DeclContexts.empty()) {
3239 DeclContext *DC = DeclContexts.pop_back_val();
3240 for (auto *SubDC : DC->decls()) {
3241 if (SubDC->isInvalidDecl())
3242 continue;
3243 if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3244 DeclContexts.push_back(CTD->getTemplatedDecl());
3245 for (auto *S : CTD->specializations())
3246 DeclContexts.push_back(S);
3247 continue;
3248 }
3249 if (auto *DC = dyn_cast<DeclContext>(SubDC))
3250 DeclContexts.push_back(DC);
3251 if (auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3252 F->addAttr(AA);
3253 continue;
3254 }
3255 }
3256 }
3257}
3258
3259void Sema::ActOnOpenMPEndAssumesDirective() {
3260 assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!");
3261 OMPAssumeScoped.pop_back();
3262}
3263
3264OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3265 ArrayRef<OMPClause *> ClauseList) {
3266 /// For target specific clauses, the requires directive cannot be
3267 /// specified after the handling of any of the target regions in the
3268 /// current compilation unit.
3269 ArrayRef<SourceLocation> TargetLocations =
3270 DSAStack->getEncounteredTargetLocs();
3271 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc();
3272 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3273 for (const OMPClause *CNew : ClauseList) {
3274 // Check if any of the requires clauses affect target regions.
3275 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3276 isa<OMPUnifiedAddressClause>(CNew) ||
3277 isa<OMPReverseOffloadClause>(CNew) ||
3278 isa<OMPDynamicAllocatorsClause>(CNew)) {
3279 Diag(Loc, diag::err_omp_directive_before_requires)
3280 << "target" << getOpenMPClauseName(CNew->getClauseKind());
3281 for (SourceLocation TargetLoc : TargetLocations) {
3282 Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3283 << "target";
3284 }
3285 } else if (!AtomicLoc.isInvalid() &&
3286 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3287 Diag(Loc, diag::err_omp_directive_before_requires)
3288 << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3289 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3290 << "atomic";
3291 }
3292 }
3293 }
3294
3295 if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
3296 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3297 ClauseList);
3298 return nullptr;
3299}
3300
3301static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3302 const ValueDecl *D,
3303 const DSAStackTy::DSAVarData &DVar,
3304 bool IsLoopIterVar) {
3305 if (DVar.RefExpr) {
3306 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3307 << getOpenMPClauseName(DVar.CKind);
3308 return;
3309 }
3310 enum {
3311 PDSA_StaticMemberShared,
3312 PDSA_StaticLocalVarShared,
3313 PDSA_LoopIterVarPrivate,
3314 PDSA_LoopIterVarLinear,
3315 PDSA_LoopIterVarLastprivate,
3316 PDSA_ConstVarShared,
3317 PDSA_GlobalVarShared,
3318 PDSA_TaskVarFirstprivate,
3319 PDSA_LocalVarPrivate,
3320 PDSA_Implicit
3321 } Reason = PDSA_Implicit;
3322 bool ReportHint = false;
3323 auto ReportLoc = D->getLocation();
3324 auto *VD = dyn_cast<VarDecl>(D);
3325 if (IsLoopIterVar) {
3326 if (DVar.CKind == OMPC_private)
3327 Reason = PDSA_LoopIterVarPrivate;
3328 else if (DVar.CKind == OMPC_lastprivate)
3329 Reason = PDSA_LoopIterVarLastprivate;
3330 else
3331 Reason = PDSA_LoopIterVarLinear;
3332 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3333 DVar.CKind == OMPC_firstprivate) {
3334 Reason = PDSA_TaskVarFirstprivate;
3335 ReportLoc = DVar.ImplicitDSALoc;
3336 } else if (VD && VD->isStaticLocal())
3337 Reason = PDSA_StaticLocalVarShared;
3338 else if (VD && VD->isStaticDataMember())
3339 Reason = PDSA_StaticMemberShared;
3340 else if (VD && VD->isFileVarDecl())
3341 Reason = PDSA_GlobalVarShared;
3342 else if (D->getType().isConstant(SemaRef.getASTContext()))
3343 Reason = PDSA_ConstVarShared;
3344 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3345 ReportHint = true;
3346 Reason = PDSA_LocalVarPrivate;
3347 }
3348 if (Reason != PDSA_Implicit) {
3349 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3350 << Reason << ReportHint
3351 << getOpenMPDirectiveName(Stack->getCurrentDirective());
3352 } else if (DVar.ImplicitDSALoc.isValid()) {
3353 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3354 << getOpenMPClauseName(DVar.CKind);
3355 }
3356}
3357
3358static OpenMPMapClauseKind
3359getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3360 bool IsAggregateOrDeclareTarget) {
3361 OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3362 switch (M) {
3363 case OMPC_DEFAULTMAP_MODIFIER_alloc:
3364 Kind = OMPC_MAP_alloc;
3365 break;
3366 case OMPC_DEFAULTMAP_MODIFIER_to:
3367 Kind = OMPC_MAP_to;
3368 break;
3369 case OMPC_DEFAULTMAP_MODIFIER_from:
3370 Kind = OMPC_MAP_from;
3371 break;
3372 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3373 Kind = OMPC_MAP_tofrom;
3374 break;
3375 case OMPC_DEFAULTMAP_MODIFIER_present:
3376 // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description]
3377 // If implicit-behavior is present, each variable referenced in the
3378 // construct in the category specified by variable-category is treated as if
3379 // it had been listed in a map clause with the map-type of alloc and
3380 // map-type-modifier of present.
3381 Kind = OMPC_MAP_alloc;
3382 break;
3383 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3384 case OMPC_DEFAULTMAP_MODIFIER_last:
3385 llvm_unreachable("Unexpected defaultmap implicit behavior");
3386 case OMPC_DEFAULTMAP_MODIFIER_none:
3387 case OMPC_DEFAULTMAP_MODIFIER_default:
3388 case OMPC_DEFAULTMAP_MODIFIER_unknown:
3389 // IsAggregateOrDeclareTarget could be true if:
3390 // 1. the implicit behavior for aggregate is tofrom
3391 // 2. it's a declare target link
3392 if (IsAggregateOrDeclareTarget) {
3393 Kind = OMPC_MAP_tofrom;
3394 break;
3395 }
3396 llvm_unreachable("Unexpected defaultmap implicit behavior");
3397 }
3398 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known");
3399 return Kind;
3400}
3401
3402namespace {
3403class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3404 DSAStackTy *Stack;
3405 Sema &SemaRef;
3406 bool ErrorFound = false;
3407 bool TryCaptureCXXThisMembers = false;
3408 CapturedStmt *CS = nullptr;
3409 const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
3410 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3411 llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete];
3412 llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
3413 ImplicitMapModifier[DefaultmapKindNum];
3414 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3415 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3416
3417 void VisitSubCaptures(OMPExecutableDirective *S) {
3418 // Check implicitly captured variables.
3419 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3420 return;
3421 if (S->getDirectiveKind() == OMPD_atomic ||
3422 S->getDirectiveKind() == OMPD_critical ||
3423 S->getDirectiveKind() == OMPD_section ||
3424 S->getDirectiveKind() == OMPD_master) {
3425 Visit(S->getAssociatedStmt());
3426 return;
3427 }
3428 visitSubCaptures(S->getInnermostCapturedStmt());
3429 // Try to capture inner this->member references to generate correct mappings
3430 // and diagnostics.
3431 if (TryCaptureCXXThisMembers ||
3432 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3433 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3434 [](const CapturedStmt::Capture &C) {
3435 return C.capturesThis();
3436 }))) {
3437 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3438 TryCaptureCXXThisMembers = true;
3439 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3440 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3441 }
3442 // In tasks firstprivates are not captured anymore, need to analyze them
3443 // explicitly.
3444 if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3445 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3446 for (OMPClause *C : S->clauses())
3447 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3448 for (Expr *Ref : FC->varlists())
3449 Visit(Ref);
3450 }
3451 }
3452 }
3453
3454public:
3455 void VisitDeclRefExpr(DeclRefExpr *E) {
3456 if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3457 E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3458 E->isInstantiationDependent())
3459 return;
3460 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3461 // Check the datasharing rules for the expressions in the clauses.
3462 if (!CS) {
3463 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3464 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3465 Visit(CED->getInit());
3466 return;
3467 }
3468 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3469 // Do not analyze internal variables and do not enclose them into
3470 // implicit clauses.
3471 return;
3472 VD = VD->getCanonicalDecl();
3473 // Skip internally declared variables.
3474 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3475 !Stack->isImplicitTaskFirstprivate(VD))
3476 return;
3477 // Skip allocators in uses_allocators clauses.
3478 if (Stack->isUsesAllocatorsDecl(VD).hasValue())
3479 return;
3480
3481 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3482 // Check if the variable has explicit DSA set and stop analysis if it so.
3483 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3484 return;
3485
3486 // Skip internally declared static variables.
3487 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3488 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3489 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3490 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3491 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3492 !Stack->isImplicitTaskFirstprivate(VD))
3493 return;
3494
3495 SourceLocation ELoc = E->getExprLoc();
3496 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3497 // The default(none) clause requires that each variable that is referenced
3498 // in the construct, and does not have a predetermined data-sharing
3499 // attribute, must have its data-sharing attribute explicitly determined
3500 // by being listed in a data-sharing attribute clause.
3501 if (DVar.CKind == OMPC_unknown &&
3502 (Stack->getDefaultDSA() == DSA_none ||
3503 Stack->getDefaultDSA() == DSA_firstprivate) &&
3504 isImplicitOrExplicitTaskingRegion(DKind) &&
3505 VarsWithInheritedDSA.count(VD) == 0) {
3506 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3507 if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) {
3508 DSAStackTy::DSAVarData DVar =
3509 Stack->getImplicitDSA(VD, /*FromParent=*/false);
3510 InheritedDSA = DVar.CKind == OMPC_unknown;
3511 }
3512 if (InheritedDSA)
3513 VarsWithInheritedDSA[VD] = E;
3514 return;
3515 }
3516
3517 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3518 // If implicit-behavior is none, each variable referenced in the
3519 // construct that does not have a predetermined data-sharing attribute
3520 // and does not appear in a to or link clause on a declare target
3521 // directive must be listed in a data-mapping attribute clause, a
3522 // data-haring attribute clause (including a data-sharing attribute
3523 // clause on a combined construct where target. is one of the
3524 // constituent constructs), or an is_device_ptr clause.
3525 OpenMPDefaultmapClauseKind ClauseKind =
3526 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3527 if (SemaRef.getLangOpts().OpenMP >= 50) {
3528 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3529 OMPC_DEFAULTMAP_MODIFIER_none;
3530 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3531 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3532 // Only check for data-mapping attribute and is_device_ptr here
3533 // since we have already make sure that the declaration does not
3534 // have a data-sharing attribute above
3535 if (!Stack->checkMappableExprComponentListsForDecl(
3536 VD, /*CurrentRegionOnly=*/true,
3537 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3538 MapExprComponents,
3539 OpenMPClauseKind) {
3540 auto MI = MapExprComponents.rbegin();
3541 auto ME = MapExprComponents.rend();
3542 return MI != ME && MI->getAssociatedDeclaration() == VD;
3543 })) {
3544 VarsWithInheritedDSA[VD] = E;
3545 return;
3546 }
3547 }
3548 }
3549 if (SemaRef.getLangOpts().OpenMP > 50) {
3550 bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3551 OMPC_DEFAULTMAP_MODIFIER_present;
3552 if (IsModifierPresent) {
3553 if (llvm::find(ImplicitMapModifier[ClauseKind],
3554 OMPC_MAP_MODIFIER_present) ==
3555 std::end(ImplicitMapModifier[ClauseKind])) {
3556 ImplicitMapModifier[ClauseKind].push_back(
3557 OMPC_MAP_MODIFIER_present);
3558 }
3559 }
3560 }
3561
3562 if (isOpenMPTargetExecutionDirective(DKind) &&
3563 !Stack->isLoopControlVariable(VD).first) {
3564 if (!Stack->checkMappableExprComponentListsForDecl(
3565 VD, /*CurrentRegionOnly=*/true,
3566 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3567 StackComponents,
3568 OpenMPClauseKind) {
3569 // Variable is used if it has been marked as an array, array
3570 // section, array shaping or the variable iself.
3571 return StackComponents.size() == 1 ||
3572 std::all_of(
3573 std::next(StackComponents.rbegin()),
3574 StackComponents.rend(),
3575 [](const OMPClauseMappableExprCommon::
3576 MappableComponent &MC) {
3577 return MC.getAssociatedDeclaration() ==
3578 nullptr &&
3579 (isa<OMPArraySectionExpr>(
3580 MC.getAssociatedExpression()) ||
3581 isa<OMPArrayShapingExpr>(
3582 MC.getAssociatedExpression()) ||
3583 isa<ArraySubscriptExpr>(
3584 MC.getAssociatedExpression()));
3585 });
3586 })) {
3587 bool IsFirstprivate = false;
3588 // By default lambdas are captured as firstprivates.
3589 if (const auto *RD =
3590 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3591 IsFirstprivate = RD->isLambda();
3592 IsFirstprivate =
3593 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3594 if (IsFirstprivate) {
3595 ImplicitFirstprivate.emplace_back(E);
3596 } else {
3597 OpenMPDefaultmapClauseModifier M =
3598 Stack->getDefaultmapModifier(ClauseKind);
3599 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3600 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3601 ImplicitMap[ClauseKind][Kind].emplace_back(E);
3602 }
3603 return;
3604 }
3605 }
3606
3607 // OpenMP [2.9.3.6, Restrictions, p.2]
3608 // A list item that appears in a reduction clause of the innermost
3609 // enclosing worksharing or parallel construct may not be accessed in an
3610 // explicit task.
3611 DVar = Stack->hasInnermostDSA(
3612 VD,
3613 [](OpenMPClauseKind C, bool AppliedToPointee) {
3614 return C == OMPC_reduction && !AppliedToPointee;
3615 },
3616 [](OpenMPDirectiveKind K) {
3617 return isOpenMPParallelDirective(K) ||
3618 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3619 },
3620 /*FromParent=*/true);
3621 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3622 ErrorFound = true;
3623 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3624 reportOriginalDsa(SemaRef, Stack, VD, DVar);
3625 return;
3626 }
3627
3628 // Define implicit data-sharing attributes for task.
3629 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3630 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3631 (Stack->getDefaultDSA() == DSA_firstprivate &&
3632 DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) &&
3633 !Stack->isLoopControlVariable(VD).first) {
3634 ImplicitFirstprivate.push_back(E);
3635 return;
3636 }
3637
3638 // Store implicitly used globals with declare target link for parent
3639 // target.
3640 if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3641 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3642 Stack->addToParentTargetRegionLinkGlobals(E);
3643 return;
3644 }
3645 }
3646 }
3647 void VisitMemberExpr(MemberExpr *E) {
3648 if (E->isTypeDependent() || E->isValueDependent() ||
3649 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3650 return;
3651 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3652 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3653 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3654 if (!FD)
3655 return;
3656 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3657 // Check if the variable has explicit DSA set and stop analysis if it
3658 // so.
3659 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3660 return;
3661
3662 if (isOpenMPTargetExecutionDirective(DKind) &&
3663 !Stack->isLoopControlVariable(FD).first &&
3664 !Stack->checkMappableExprComponentListsForDecl(
3665 FD, /*CurrentRegionOnly=*/true,
3666 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3667 StackComponents,
3668 OpenMPClauseKind) {
3669 return isa<CXXThisExpr>(
3670 cast<MemberExpr>(
3671 StackComponents.back().getAssociatedExpression())
3672 ->getBase()
3673 ->IgnoreParens());
3674 })) {
3675 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3676 // A bit-field cannot appear in a map clause.
3677 //
3678 if (FD->isBitField())
3679 return;
3680
3681 // Check to see if the member expression is referencing a class that
3682 // has already been explicitly mapped
3683 if (Stack->isClassPreviouslyMapped(TE->getType()))
3684 return;
3685
3686 OpenMPDefaultmapClauseModifier Modifier =
3687 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3688 OpenMPDefaultmapClauseKind ClauseKind =
3689 getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD);
3690 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3691 Modifier, /*IsAggregateOrDeclareTarget*/ true);
3692 ImplicitMap[ClauseKind][Kind].emplace_back(E);
3693 return;
3694 }
3695
3696 SourceLocation ELoc = E->getExprLoc();
3697 // OpenMP [2.9.3.6, Restrictions, p.2]
3698 // A list item that appears in a reduction clause of the innermost
3699 // enclosing worksharing or parallel construct may not be accessed in
3700 // an explicit task.
3701 DVar = Stack->hasInnermostDSA(
3702 FD,
3703 [](OpenMPClauseKind C, bool AppliedToPointee) {
3704 return C == OMPC_reduction && !AppliedToPointee;
3705 },
3706 [](OpenMPDirectiveKind K) {
3707 return isOpenMPParallelDirective(K) ||
3708 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3709 },
3710 /*FromParent=*/true);
3711 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3712 ErrorFound = true;
3713 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3714 reportOriginalDsa(SemaRef, Stack, FD, DVar);
3715 return;
3716 }
3717
3718 // Define implicit data-sharing attributes for task.
3719 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3720 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3721 !Stack->isLoopControlVariable(FD).first) {
3722 // Check if there is a captured expression for the current field in the
3723 // region. Do not mark it as firstprivate unless there is no captured
3724 // expression.
3725 // TODO: try to make it firstprivate.
3726 if (DVar.CKind != OMPC_unknown)
3727 ImplicitFirstprivate.push_back(E);
3728 }
3729 return;
3730 }
3731 if (isOpenMPTargetExecutionDirective(DKind)) {
3732 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
3733 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
3734 Stack->getCurrentDirective(),
3735 /*NoDiagnose=*/true))
3736 return;
3737 const auto *VD = cast<ValueDecl>(
3738 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3739 if (!Stack->checkMappableExprComponentListsForDecl(
3740 VD, /*CurrentRegionOnly=*/true,
3741 [&CurComponents](
3742 OMPClauseMappableExprCommon::MappableExprComponentListRef
3743 StackComponents,
3744 OpenMPClauseKind) {
3745 auto CCI = CurComponents.rbegin();
3746 auto CCE = CurComponents.rend();
3747 for (const auto &SC : llvm::reverse(StackComponents)) {
3748 // Do both expressions have the same kind?
3749 if (CCI->getAssociatedExpression()->getStmtClass() !=
3750 SC.getAssociatedExpression()->getStmtClass())
3751 if (!((isa<OMPArraySectionExpr>(
3752 SC.getAssociatedExpression()) ||
3753 isa<OMPArrayShapingExpr>(
3754 SC.getAssociatedExpression())) &&
3755 isa<ArraySubscriptExpr>(
3756 CCI->getAssociatedExpression())))
3757 return false;
3758
3759 const Decl *CCD = CCI->getAssociatedDeclaration();
3760 const Decl *SCD = SC.getAssociatedDeclaration();
3761 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3762 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3763 if (SCD != CCD)
3764 return false;
3765 std::advance(CCI, 1);
3766 if (CCI == CCE)
3767 break;
3768 }
3769 return true;
3770 })) {
3771 Visit(E->getBase());
3772 }
3773 } else if (!TryCaptureCXXThisMembers) {
3774 Visit(E->getBase());
3775 }
3776 }
3777 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
3778 for (OMPClause *C : S->clauses()) {
3779 // Skip analysis of arguments of implicitly defined firstprivate clause
3780 // for task|target directives.
3781 // Skip analysis of arguments of implicitly defined map clause for target
3782 // directives.
3783 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3784 C->isImplicit() &&
3785 !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) {
3786 for (Stmt *CC : C->children()) {
3787 if (CC)
3788 Visit(CC);
3789 }
3790 }
3791 }
3792 // Check implicitly captured variables.
3793 VisitSubCaptures(S);
3794 }
3795 void VisitStmt(Stmt *S) {
3796 for (Stmt *C : S->children()) {
3797 if (C) {
3798 // Check implicitly captured variables in the task-based directives to
3799 // check if they must be firstprivatized.
3800 Visit(C);
3801 }
3802 }
3803 }
3804
3805 void visitSubCaptures(CapturedStmt *S) {
3806 for (const CapturedStmt::Capture &Cap : S->captures()) {
3807 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3808 continue;
3809 VarDecl *VD = Cap.getCapturedVar();
3810 // Do not try to map the variable if it or its sub-component was mapped
3811 // already.
3812 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3813 Stack->checkMappableExprComponentListsForDecl(
3814 VD, /*CurrentRegionOnly=*/true,
3815 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
3816 OpenMPClauseKind) { return true; }))
3817 continue;
3818 DeclRefExpr *DRE = buildDeclRefExpr(
3819 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3820 Cap.getLocation(), /*RefersToCapture=*/true);
3821 Visit(DRE);
3822 }
3823 }
3824 bool isErrorFound() const { return ErrorFound; }
3825 ArrayRef<Expr *> getImplicitFirstprivate() const {
3826 return ImplicitFirstprivate;
3827 }
3828 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK,
3829 OpenMPMapClauseKind MK) const {
3830 return ImplicitMap[DK][MK];
3831 }
3832 ArrayRef<OpenMPMapModifierKind>
3833 getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const {
3834 return ImplicitMapModifier[Kind];
3835 }
3836 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
3837 return VarsWithInheritedDSA;
3838 }
3839
3840 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
3841 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3842 // Process declare target link variables for the target directives.
3843 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3844 for (DeclRefExpr *E : Stack->getLinkGlobals())
3845 Visit(E);
3846 }
3847 }
3848};
3849} // namespace
3850
3851void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
3852 switch (DKind) {
3853 case OMPD_parallel:
3854 case OMPD_parallel_for:
3855 case OMPD_parallel_for_simd:
3856 case OMPD_parallel_sections:
3857 case OMPD_parallel_master:
3858 case OMPD_teams:
3859 case OMPD_teams_distribute:
3860 case OMPD_teams_distribute_simd: {
3861 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3862 QualType KmpInt32PtrTy =
3863 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3864 Sema::CapturedParamNameType Params[] = {
3865 std::make_pair(".global_tid.", KmpInt32PtrTy),
3866 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3867 std::make_pair(StringRef(), QualType()) // __context with shared vars
3868 };
3869 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3870 Params);
3871 break;
3872 }
3873 case OMPD_target_teams:
3874 case OMPD_target_parallel:
3875 case OMPD_target_parallel_for:
3876 case OMPD_target_parallel_for_simd:
3877 case OMPD_target_teams_distribute:
3878 case OMPD_target_teams_distribute_simd: {
3879 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3880 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3881 QualType KmpInt32PtrTy =
3882 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3883 QualType Args[] = {VoidPtrTy};
3884 FunctionProtoType::ExtProtoInfo EPI;
3885 EPI.Variadic = true;
3886 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3887 Sema::CapturedParamNameType Params[] = {
3888 std::make_pair(".global_tid.", KmpInt32Ty),
3889 std::make_pair(".part_id.", KmpInt32PtrTy),
3890 std::make_pair(".privates.", VoidPtrTy),
3891 std::make_pair(
3892 ".copy_fn.",
3893 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3894 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3895 std::make_pair(StringRef(), QualType()) // __context with shared vars
3896 };
3897 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3898 Params, /*OpenMPCaptureLevel=*/0);
3899 // Mark this captured region as inlined, because we don't use outlined
3900 // function directly.
3901 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3902 AlwaysInlineAttr::CreateImplicit(
3903 Context, {}, AttributeCommonInfo::AS_Keyword,
3904 AlwaysInlineAttr::Keyword_forceinline));
3905 Sema::CapturedParamNameType ParamsTarget[] = {
3906 std::make_pair(StringRef(), QualType()) // __context with shared vars
3907 };
3908 // Start a captured region for 'target' with no implicit parameters.
3909 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3910 ParamsTarget, /*OpenMPCaptureLevel=*/1);
3911 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
3912 std::make_pair(".global_tid.", KmpInt32PtrTy),
3913 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3914 std::make_pair(StringRef(), QualType()) // __context with shared vars
3915 };
3916 // Start a captured region for 'teams' or 'parallel'. Both regions have
3917 // the same implicit parameters.
3918 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3919 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
3920 break;
3921 }
3922 case OMPD_target:
3923 case OMPD_target_simd: {
3924 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3925 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3926 QualType KmpInt32PtrTy =
3927 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3928 QualType Args[] = {VoidPtrTy};
3929 FunctionProtoType::ExtProtoInfo EPI;
3930 EPI.Variadic = true;
3931 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3932 Sema::CapturedParamNameType Params[] = {
3933 std::make_pair(".global_tid.", KmpInt32Ty),
3934 std::make_pair(".part_id.", KmpInt32PtrTy),
3935 std::make_pair(".privates.", VoidPtrTy),
3936 std::make_pair(
3937 ".copy_fn.",
3938 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3939 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3940 std::make_pair(StringRef(), QualType()) // __context with shared vars
3941 };
3942 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3943 Params, /*OpenMPCaptureLevel=*/0);
3944 // Mark this captured region as inlined, because we don't use outlined
3945 // function directly.
3946 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3947 AlwaysInlineAttr::CreateImplicit(
3948 Context, {}, AttributeCommonInfo::AS_Keyword,
3949 AlwaysInlineAttr::Keyword_forceinline));
3950 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3951 std::make_pair(StringRef(), QualType()),
3952 /*OpenMPCaptureLevel=*/1);
3953 break;
3954 }
3955 case OMPD_atomic:
3956 case OMPD_critical:
3957 case OMPD_section:
3958 case OMPD_master:
3959 break;
3960 case OMPD_simd:
3961 case OMPD_for:
3962 case OMPD_for_simd:
3963 case OMPD_sections:
3964 case OMPD_single:
3965 case OMPD_taskgroup:
3966 case OMPD_distribute:
3967 case OMPD_distribute_simd:
3968 case OMPD_ordered:
3969 case OMPD_target_data: {
3970 Sema::CapturedParamNameType Params[] = {
3971 std::make_pair(StringRef(), QualType()) // __context with shared vars
3972 };
3973 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3974 Params);
3975 break;
3976 }
3977 case OMPD_task: {
3978 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3979 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3980 QualType KmpInt32PtrTy =
3981 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3982 QualType Args[] = {VoidPtrTy};
3983 FunctionProtoType::ExtProtoInfo EPI;
3984 EPI.Variadic = true;
3985 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3986 Sema::CapturedParamNameType Params[] = {
3987 std::make_pair(".global_tid.", KmpInt32Ty),
3988 std::make_pair(".part_id.", KmpInt32PtrTy),
3989 std::make_pair(".privates.", VoidPtrTy),
3990 std::make_pair(
3991 ".copy_fn.",
3992 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3993 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3994 std::make_pair(StringRef(), QualType()) // __context with shared vars
3995 };
3996 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3997 Params);
3998 // Mark this captured region as inlined, because we don't use outlined
3999 // function directly.
4000 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4001 AlwaysInlineAttr::CreateImplicit(
4002 Context, {}, AttributeCommonInfo::AS_Keyword,
4003 AlwaysInlineAttr::Keyword_forceinline));
4004 break;
4005 }
4006 case OMPD_taskloop:
4007 case OMPD_taskloop_simd:
4008 case OMPD_master_taskloop:
4009 case OMPD_master_taskloop_simd: {
4010 QualType KmpInt32Ty =
4011 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4012 .withConst();
4013 QualType KmpUInt64Ty =
4014 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4015 .withConst();
4016 QualType KmpInt64Ty =
4017 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4018 .withConst();
4019 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4020 QualType KmpInt32PtrTy =
4021 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4022 QualType Args[] = {VoidPtrTy};
4023 FunctionProtoType::ExtProtoInfo EPI;
4024 EPI.Variadic = true;
4025 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4026 Sema::CapturedParamNameType Params[] = {
4027 std::make_pair(".global_tid.", KmpInt32Ty),
4028 std::make_pair(".part_id.", KmpInt32PtrTy),
4029 std::make_pair(".privates.", VoidPtrTy),
4030 std::make_pair(
4031 ".copy_fn.",
4032 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4033 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4034 std::make_pair(".lb.", KmpUInt64Ty),
4035 std::make_pair(".ub.", KmpUInt64Ty),
4036 std::make_pair(".st.", KmpInt64Ty),
4037 std::make_pair(".liter.", KmpInt32Ty),
4038 std::make_pair(".reductions.", VoidPtrTy),
4039 std::make_pair(StringRef(), QualType()) // __context with shared vars
4040 };
4041 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4042 Params);
4043 // Mark this captured region as inlined, because we don't use outlined
4044 // function directly.
4045 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4046 AlwaysInlineAttr::CreateImplicit(
4047 Context, {}, AttributeCommonInfo::AS_Keyword,
4048 AlwaysInlineAttr::Keyword_forceinline));
4049 break;
4050 }
4051 case OMPD_parallel_master_taskloop:
4052 case OMPD_parallel_master_taskloop_simd: {
4053 QualType KmpInt32Ty =
4054 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4055 .withConst();
4056 QualType KmpUInt64Ty =
4057 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4058 .withConst();
4059 QualType KmpInt64Ty =
4060 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4061 .withConst();
4062 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4063 QualType KmpInt32PtrTy =
4064 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4065 Sema::CapturedParamNameType ParamsParallel[] = {
4066 std::make_pair(".global_tid.", KmpInt32PtrTy),
4067 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4068 std::make_pair(StringRef(), QualType()) // __context with shared vars
4069 };
4070 // Start a captured region for 'parallel'.
4071 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4072 ParamsParallel, /*OpenMPCaptureLevel=*/0);
4073 QualType Args[] = {VoidPtrTy};
4074 FunctionProtoType::ExtProtoInfo EPI;
4075 EPI.Variadic = true;
4076 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4077 Sema::CapturedParamNameType Params[] = {
4078 std::make_pair(".global_tid.", KmpInt32Ty),
4079 std::make_pair(".part_id.", KmpInt32PtrTy),
4080 std::make_pair(".privates.", VoidPtrTy),
4081 std::make_pair(
4082 ".copy_fn.",
4083 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4084 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4085 std::make_pair(".lb.", KmpUInt64Ty),
4086 std::make_pair(".ub.", KmpUInt64Ty),
4087 std::make_pair(".st.", KmpInt64Ty),
4088 std::make_pair(".liter.", KmpInt32Ty),
4089 std::make_pair(".reductions.", VoidPtrTy),
4090 std::make_pair(StringRef(), QualType()) // __context with shared vars
4091 };
4092 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4093 Params, /*OpenMPCaptureLevel=*/1);
4094 // Mark this captured region as inlined, because we don't use outlined
4095 // function directly.
4096 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4097 AlwaysInlineAttr::CreateImplicit(
4098 Context, {}, AttributeCommonInfo::AS_Keyword,
4099 AlwaysInlineAttr::Keyword_forceinline));
4100 break;
4101 }
4102 case OMPD_distribute_parallel_for_simd:
4103 case OMPD_distribute_parallel_for: {
4104 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4105 QualType KmpInt32PtrTy =
4106 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4107 Sema::CapturedParamNameType Params[] = {
4108 std::make_pair(".global_tid.", KmpInt32PtrTy),
4109 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4110 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4111 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4112 std::make_pair(StringRef(), QualType()) // __context with shared vars
4113 };
4114 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4115 Params);
4116 break;
4117 }
4118 case OMPD_target_teams_distribute_parallel_for:
4119 case OMPD_target_teams_distribute_parallel_for_simd: {
4120 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4121 QualType KmpInt32PtrTy =
4122 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4123 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4124
4125 QualType Args[] = {VoidPtrTy};
4126 FunctionProtoType::ExtProtoInfo EPI;
4127 EPI.Variadic = true;
4128 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4129 Sema::CapturedParamNameType Params[] = {
4130 std::make_pair(".global_tid.", KmpInt32Ty),
4131 std::make_pair(".part_id.", KmpInt32PtrTy),
4132 std::make_pair(".privates.", VoidPtrTy),
4133 std::make_pair(
4134 ".copy_fn.",
4135 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4136 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4137 std::make_pair(StringRef(), QualType()) // __context with shared vars
4138 };
4139 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4140 Params, /*OpenMPCaptureLevel=*/0);
4141 // Mark this captured region as inlined, because we don't use outlined
4142 // function directly.
4143 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4144 AlwaysInlineAttr::CreateImplicit(
4145 Context, {}, AttributeCommonInfo::AS_Keyword,
4146 AlwaysInlineAttr::Keyword_forceinline));
4147 Sema::CapturedParamNameType ParamsTarget[] = {
4148 std::make_pair(StringRef(), QualType()) // __context with shared vars
4149 };
4150 // Start a captured region for 'target' with no implicit parameters.
4151 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4152 ParamsTarget, /*OpenMPCaptureLevel=*/1);
4153
4154 Sema::CapturedParamNameType ParamsTeams[] = {
4155 std::make_pair(".global_tid.", KmpInt32PtrTy),
4156 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4157 std::make_pair(StringRef(), QualType()) // __context with shared vars
4158 };
4159 // Start a captured region for 'target' with no implicit parameters.
4160 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4161 ParamsTeams, /*OpenMPCaptureLevel=*/2);
4162
4163 Sema::CapturedParamNameType ParamsParallel[] = {
4164 std::make_pair(".global_tid.", KmpInt32PtrTy),
4165 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4166 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4167 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4168 std::make_pair(StringRef(), QualType()) // __context with shared vars
4169 };
4170 // Start a captured region for 'teams' or 'parallel'. Both regions have
4171 // the same implicit parameters.
4172 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4173 ParamsParallel, /*OpenMPCaptureLevel=*/3);
4174 break;
4175 }
4176
4177 case OMPD_teams_distribute_parallel_for:
4178 case OMPD_teams_distribute_parallel_for_simd: {
4179 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4180 QualType KmpInt32PtrTy =
4181 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4182
4183 Sema::CapturedParamNameType ParamsTeams[] = {
4184 std::make_pair(".global_tid.", KmpInt32PtrTy),
4185 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4186 std::make_pair(StringRef(), QualType()) // __context with shared vars
4187 };
4188 // Start a captured region for 'target' with no implicit parameters.
4189 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4190 ParamsTeams, /*OpenMPCaptureLevel=*/0);
4191
4192 Sema::CapturedParamNameType ParamsParallel[] = {
4193 std::make_pair(".global_tid.", KmpInt32PtrTy),
4194 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4195 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4196 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4197 std::make_pair(StringRef(), QualType()) // __context with shared vars
4198 };
4199 // Start a captured region for 'teams' or 'parallel'. Both regions have
4200 // the same implicit parameters.
4201 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4202 ParamsParallel, /*OpenMPCaptureLevel=*/1);
4203 break;
4204 }
4205 case OMPD_target_update:
4206 case OMPD_target_enter_data:
4207 case OMPD_target_exit_data: {
4208 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4209 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4210 QualType KmpInt32PtrTy =
4211 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4212 QualType Args[] = {VoidPtrTy};
4213 FunctionProtoType::ExtProtoInfo EPI;
4214 EPI.Variadic = true;
4215 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4216 Sema::CapturedParamNameType Params[] = {
4217 std::make_pair(".global_tid.", KmpInt32Ty),
4218 std::make_pair(".part_id.", KmpInt32PtrTy),
4219 std::make_pair(".privates.", VoidPtrTy),
4220 std::make_pair(
4221 ".copy_fn.",
4222 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4223 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4224 std::make_pair(StringRef(), QualType()) // __context with shared vars
4225 };
4226 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4227 Params);
4228 // Mark this captured region as inlined, because we don't use outlined
4229 // function directly.
4230 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4231 AlwaysInlineAttr::CreateImplicit(
4232 Context, {}, AttributeCommonInfo::AS_Keyword,
4233 AlwaysInlineAttr::Keyword_forceinline));
4234 break;
4235 }
4236 case OMPD_threadprivate:
4237 case OMPD_allocate:
4238 case OMPD_taskyield:
4239 case OMPD_barrier:
4240 case OMPD_taskwait:
4241 case OMPD_cancellation_point:
4242 case OMPD_cancel:
4243 case OMPD_flush:
4244 case OMPD_depobj:
4245 case OMPD_scan:
4246 case OMPD_declare_reduction:
4247 case OMPD_declare_mapper:
4248 case OMPD_declare_simd:
4249 case OMPD_declare_target:
4250 case OMPD_end_declare_target:
4251 case OMPD_requires:
4252 case OMPD_declare_variant:
4253 case OMPD_begin_declare_variant:
4254 case OMPD_end_declare_variant:
4255 llvm_unreachable("OpenMP Directive is not allowed");
4256 case OMPD_unknown:
4257 default:
4258 llvm_unreachable("Unknown OpenMP directive");
4259 }
4260 DSAStack->setContext(CurContext);
4261}
4262
4263int Sema::getNumberOfConstructScopes(unsigned Level) const {
4264 return getOpenMPCaptureLevels(DSAStack->getDirective(Level));
4265}
4266
4267int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4268 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4269 getOpenMPCaptureRegions(CaptureRegions, DKind);
4270 return CaptureRegions.size();
4271}
4272
4273static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4274 Expr *CaptureExpr, bool WithInit,
4275 bool AsExpression) {
4276 assert(CaptureExpr);
4277 ASTContext &C = S.getASTContext();
4278 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4279 QualType Ty = Init->getType();
4280 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4281 if (S.getLangOpts().CPlusPlus) {
4282 Ty = C.getLValueReferenceType(Ty);
4283 } else {
4284 Ty = C.getPointerType(Ty);
4285 ExprResult Res =
4286 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4287 if (!Res.isUsable())
4288 return nullptr;
4289 Init = Res.get();
4290 }
4291 WithInit = true;
4292 }
4293 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
4294 CaptureExpr->getBeginLoc());
4295 if (!WithInit)
4296 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4297 S.CurContext->addHiddenDecl(CED);
4298 Sema::TentativeAnalysisScope Trap(S);
4299 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4300 return CED;
4301}
4302
4303static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4304 bool WithInit) {
4305 OMPCapturedExprDecl *CD;
4306 if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4307 CD = cast<OMPCapturedExprDecl>(VD);
4308 else
4309 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4310 /*AsExpression=*/false);
4311 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4312 CaptureExpr->getExprLoc());
4313}
4314
4315static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
4316 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4317 if (!Ref) {
4318 OMPCapturedExprDecl *CD = buildCaptureDecl(
4319 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
4320 /*WithInit=*/true, /*AsExpression=*/true);
4321 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4322 CaptureExpr->getExprLoc());
4323 }
4324 ExprResult Res = Ref;
4325 if (!S.getLangOpts().CPlusPlus &&
4326 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4327 Ref->getType()->isPointerType()) {
4328 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4329 if (!Res.isUsable())
4330 return ExprError();
4331 }
4332 return S.DefaultLvalueConversion(Res.get());
4333}
4334
4335namespace {
4336// OpenMP directives parsed in this section are represented as a
4337// CapturedStatement with an associated statement. If a syntax error
4338// is detected during the parsing of the associated statement, the
4339// compiler must abort processing and close the CapturedStatement.
4340//
4341// Combined directives such as 'target parallel' have more than one
4342// nested CapturedStatements. This RAII ensures that we unwind out
4343// of all the nested CapturedStatements when an error is found.
4344class CaptureRegionUnwinderRAII {
4345private:
4346 Sema &S;
4347 bool &ErrorFound;
4348 OpenMPDirectiveKind DKind = OMPD_unknown;
4349
4350public:
4351 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4352 OpenMPDirectiveKind DKind)
4353 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4354 ~CaptureRegionUnwinderRAII() {
4355 if (ErrorFound) {
4356 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4357 while (--ThisCaptureLevel >= 0)
4358 S.ActOnCapturedRegionError();
4359 }
4360 }
4361};
4362} // namespace
4363
4364void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4365 // Capture variables captured by reference in lambdas for target-based
4366 // directives.
4367 if (!CurContext->isDependentContext() &&
4368 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) ||
4369 isOpenMPTargetDataManagementDirective(
4370 DSAStack->getCurrentDirective()))) {
4371 QualType Type = V->getType();
4372 if (const auto *RD = Type.getCanonicalType()
4373 .getNonReferenceType()
4374 ->getAsCXXRecordDecl()) {
4375 bool SavedForceCaptureByReferenceInTargetExecutable =
4376 DSAStack->isForceCaptureByReferenceInTargetExecutable();
4377 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4378 /*V=*/true);
4379 if (RD->isLambda()) {
4380 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
4381 FieldDecl *ThisCapture;
4382 RD->getCaptureFields(Captures, ThisCapture);
4383 for (const LambdaCapture &LC : RD->captures()) {
4384 if (LC.getCaptureKind() == LCK_ByRef) {
4385 VarDecl *VD = LC.getCapturedVar();
4386 DeclContext *VDC = VD->getDeclContext();
4387 if (!VDC->Encloses(CurContext))
4388 continue;
4389 MarkVariableReferenced(LC.getLocation(), VD);
4390 } else if (LC.getCaptureKind() == LCK_This) {
4391 QualType ThisTy = getCurrentThisType();
4392 if (!ThisTy.isNull() &&
4393 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4394 CheckCXXThisCapture(LC.getLocation());
4395 }
4396 }
4397 }
4398 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4399 SavedForceCaptureByReferenceInTargetExecutable);
4400 }
4401 }
4402}
4403
4404static bool checkOrderedOrderSpecified(Sema &S,
4405 const ArrayRef<OMPClause *> Clauses) {
4406 const OMPOrderedClause *Ordered = nullptr;
4407 const OMPOrderClause *Order = nullptr;
4408
4409 for (const OMPClause *Clause : Clauses) {
4410 if (Clause->getClauseKind() == OMPC_ordered)
4411 Ordered = cast<OMPOrderedClause>(Clause);
4412 else if (Clause->getClauseKind() == OMPC_order) {
4413 Order = cast<OMPOrderClause>(Clause);
4414 if (Order->getKind() != OMPC_ORDER_concurrent)
4415 Order = nullptr;
4416 }
4417 if (Ordered && Order)
4418 break;
4419 }
4420
4421 if (Ordered && Order) {
4422 S.Diag(Order->getKindKwLoc(),
4423 diag::err_omp_simple_clause_incompatible_with_ordered)
4424 << getOpenMPClauseName(OMPC_order)
4425 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4426 << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4427 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4428 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4429 return true;
4430 }
4431 return false;
4432}
4433
4434StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4435 ArrayRef<OMPClause *> Clauses) {
4436 if (DSAStack->getCurrentDirective() == OMPD_atomic ||
4437 DSAStack->getCurrentDirective() == OMPD_critical ||
4438 DSAStack->getCurrentDirective() == OMPD_section ||
4439 DSAStack->getCurrentDirective() == OMPD_master)
4440 return S;
4441
4442 bool ErrorFound = false;
4443 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4444 *this, ErrorFound, DSAStack->getCurrentDirective());
4445 if (!S.isUsable()) {
4446 ErrorFound = true;
4447 return StmtError();
4448 }
4449
4450 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4451 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
4452 OMPOrderedClause *OC = nullptr;
4453 OMPScheduleClause *SC = nullptr;
4454 SmallVector<const OMPLinearClause *, 4> LCs;
4455 SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4456 // This is required for proper codegen.
4457 for (OMPClause *Clause : Clauses) {
4458 if (!LangOpts.OpenMPSimd &&
4459 isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
4460 Clause->getClauseKind() == OMPC_in_reduction) {
4461 // Capture taskgroup task_reduction descriptors inside the tasking regions
4462 // with the corresponding in_reduction items.
4463 auto *IRC = cast<OMPInReductionClause>(Clause);
4464 for (Expr *E : IRC->taskgroup_descriptors())
4465 if (E)
4466 MarkDeclarationsReferencedInExpr(E);
4467 }
4468 if (isOpenMPPrivate(Clause->getClauseKind()) ||
4469 Clause->getClauseKind() == OMPC_copyprivate ||
4470 (getLangOpts().OpenMPUseTLS &&
4471 getASTContext().getTargetInfo().isTLSSupported() &&
4472 Clause->getClauseKind() == OMPC_copyin)) {
4473 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4474 // Mark all variables in private list clauses as used in inner region.
4475 for (Stmt *VarRef : Clause->children()) {
4476 if (auto *E = cast_or_null<Expr>(VarRef)) {
4477 MarkDeclarationsReferencedInExpr(E);
4478 }
4479 }
4480 DSAStack->setForceVarCapturing(/*V=*/false);
4481 } else if (CaptureRegions.size() > 1 ||
4482 CaptureRegions.back() != OMPD_unknown) {
4483 if (auto *C = OMPClauseWithPreInit::get(Clause))
4484 PICs.push_back(C);
4485 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4486 if (Expr *E = C->getPostUpdateExpr())
4487 MarkDeclarationsReferencedInExpr(E);
4488 }
4489 }
4490 if (Clause->getClauseKind() == OMPC_schedule)
4491 SC = cast<OMPScheduleClause>(Clause);
4492 else if (Clause->getClauseKind() == OMPC_ordered)
4493 OC = cast<OMPOrderedClause>(Clause);
4494 else if (Clause->getClauseKind() == OMPC_linear)
4495 LCs.push_back(cast<OMPLinearClause>(Clause));
4496 }
4497 // Capture allocator expressions if used.
4498 for (Expr *E : DSAStack->getInnerAllocators())
4499 MarkDeclarationsReferencedInExpr(E);
4500 // OpenMP, 2.7.1 Loop Construct, Restrictions
4501 // The nonmonotonic modifier cannot be specified if an ordered clause is
4502 // specified.
4503 if (SC &&
4504 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4505 SC->getSecondScheduleModifier() ==
4506 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4507 OC) {
4508 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4509 ? SC->getFirstScheduleModifierLoc()
4510 : SC->getSecondScheduleModifierLoc(),
4511 diag::err_omp_simple_clause_incompatible_with_ordered)
4512 << getOpenMPClauseName(OMPC_schedule)
4513 << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4514 OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4515 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4516 ErrorFound = true;
4517 }
4518 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4519 // If an order(concurrent) clause is present, an ordered clause may not appear
4520 // on the same directive.
4521 if (checkOrderedOrderSpecified(*this, Clauses))
4522 ErrorFound = true;
4523 if (!LCs.empty() && OC && OC->getNumForLoops()) {
4524 for (const OMPLinearClause *C : LCs) {
4525 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4526 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4527 }
4528 ErrorFound = true;
4529 }
4530 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
4531 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
4532 OC->getNumForLoops()) {
4533 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4534 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
4535 ErrorFound = true;
4536 }
4537 if (ErrorFound) {
4538 return StmtError();
4539 }
4540 StmtResult SR = S;
4541 unsigned CompletedRegions = 0;
4542 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4543 // Mark all variables in private list clauses as used in inner region.
4544 // Required for proper codegen of combined directives.
4545 // TODO: add processing for other clauses.
4546 if (ThisCaptureRegion != OMPD_unknown) {
4547 for (const clang::OMPClauseWithPreInit *C : PICs) {
4548 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4549 // Find the particular capture region for the clause if the
4550 // directive is a combined one with multiple capture regions.
4551 // If the directive is not a combined one, the capture region
4552 // associated with the clause is OMPD_unknown and is generated
4553 // only once.
4554 if (CaptureRegion == ThisCaptureRegion ||
4555 CaptureRegion == OMPD_unknown) {
4556 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4557 for (Decl *D : DS->decls())
4558 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4559 }
4560 }
4561 }
4562 }
4563 if (ThisCaptureRegion == OMPD_target) {
4564 // Capture allocator traits in the target region. They are used implicitly
4565 // and, thus, are not captured by default.
4566 for (OMPClause *C : Clauses) {
4567 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4568 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4569 ++I) {
4570 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4571 if (Expr *E = D.AllocatorTraits)
4572 MarkDeclarationsReferencedInExpr(E);
4573 }
4574 continue;
4575 }
4576 }
4577 }
4578 if (++CompletedRegions == CaptureRegions.size())
4579 DSAStack->setBodyComplete();
4580 SR = ActOnCapturedRegionEnd(SR.get());
4581 }
4582 return SR;
4583}
4584
4585static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4586 OpenMPDirectiveKind CancelRegion,
4587 SourceLocation StartLoc) {
4588 // CancelRegion is only needed for cancel and cancellation_point.
4589 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4590 return false;
4591
4592 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4593 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4594 return false;
4595
4596 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4597 << getOpenMPDirectiveName(CancelRegion);
4598 return true;
4599}
4600
4601static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4602 OpenMPDirectiveKind CurrentRegion,
4603 const DeclarationNameInfo &CurrentName,
4604 OpenMPDirectiveKind CancelRegion,
4605 SourceLocation StartLoc) {
4606 if (Stack->getCurScope()) {
4607 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4608 OpenMPDirectiveKind OffendingRegion = ParentRegion;
4609 bool NestingProhibited = false;
4610 bool CloseNesting = true;
4611 bool OrphanSeen = false;
4612 enum {
4613 NoRecommend,
4614 ShouldBeInParallelRegion,
4615 ShouldBeInOrderedRegion,
4616 ShouldBeInTargetRegion,
4617 ShouldBeInTeamsRegion,
4618 ShouldBeInLoopSimdRegion,
4619 } Recommend = NoRecommend;
4620 if (isOpenMPSimdDirective(ParentRegion) &&
4621 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4622 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4623 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4624 CurrentRegion != OMPD_scan))) {
4625 // OpenMP [2.16, Nesting of Regions]
4626 // OpenMP constructs may not be nested inside a simd region.
4627 // OpenMP [2.8.1,simd Construct, Restrictions]
4628 // An ordered construct with the simd clause is the only OpenMP
4629 // construct that can appear in the simd region.
4630 // Allowing a SIMD construct nested in another SIMD construct is an
4631 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4632 // message.
4633 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4634 // The only OpenMP constructs that can be encountered during execution of
4635 // a simd region are the atomic construct, the loop construct, the simd
4636 // construct and the ordered construct with the simd clause.
4637 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4638 ? diag::err_omp_prohibited_region_simd
4639 : diag::warn_omp_nesting_simd)
4640 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4641 return CurrentRegion != OMPD_simd;
4642 }
4643 if (ParentRegion == OMPD_atomic) {
4644 // OpenMP [2.16, Nesting of Regions]
4645 // OpenMP constructs may not be nested inside an atomic region.
4646 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4647 return true;
4648 }
4649 if (CurrentRegion == OMPD_section) {
4650 // OpenMP [2.7.2, sections Construct, Restrictions]
4651 // Orphaned section directives are prohibited. That is, the section
4652 // directives must appear within the sections construct and must not be
4653 // encountered elsewhere in the sections region.
4654 if (ParentRegion != OMPD_sections &&
4655 ParentRegion != OMPD_parallel_sections) {
4656 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4657 << (ParentRegion != OMPD_unknown)
4658 << getOpenMPDirectiveName(ParentRegion);
4659 return true;
4660 }
4661 return false;
4662 }
4663 // Allow some constructs (except teams and cancellation constructs) to be
4664 // orphaned (they could be used in functions, called from OpenMP regions
4665 // with the required preconditions).
4666 if (ParentRegion == OMPD_unknown &&
4667 !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4668 CurrentRegion != OMPD_cancellation_point &&
4669 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4670 return false;
4671 if (CurrentRegion == OMPD_cancellation_point ||
4672 CurrentRegion == OMPD_cancel) {
4673 // OpenMP [2.16, Nesting of Regions]
4674 // A cancellation point construct for which construct-type-clause is
4675 // taskgroup must be nested inside a task construct. A cancellation
4676 // point construct for which construct-type-clause is not taskgroup must
4677 // be closely nested inside an OpenMP construct that matches the type
4678 // specified in construct-type-clause.
4679 // A cancel construct for which construct-type-clause is taskgroup must be
4680 // nested inside a task construct. A cancel construct for which
4681 // construct-type-clause is not taskgroup must be closely nested inside an
4682 // OpenMP construct that matches the type specified in
4683 // construct-type-clause.
4684 NestingProhibited =
4685 !((CancelRegion == OMPD_parallel &&
4686 (ParentRegion == OMPD_parallel ||
4687 ParentRegion == OMPD_target_parallel)) ||
4688 (CancelRegion == OMPD_for &&
4689 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4690 ParentRegion == OMPD_target_parallel_for ||
4691 ParentRegion == OMPD_distribute_parallel_for ||
4692 ParentRegion == OMPD_teams_distribute_parallel_for ||
4693 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4694 (CancelRegion == OMPD_taskgroup &&
4695 (ParentRegion == OMPD_task ||
4696 (SemaRef.getLangOpts().OpenMP >= 50 &&
4697 (ParentRegion == OMPD_taskloop ||
4698 ParentRegion == OMPD_master_taskloop ||
4699 ParentRegion == OMPD_parallel_master_taskloop)))) ||
4700 (CancelRegion == OMPD_sections &&
4701 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4702 ParentRegion == OMPD_parallel_sections)));
4703 OrphanSeen = ParentRegion == OMPD_unknown;
4704 } else if (CurrentRegion == OMPD_master) {
4705 // OpenMP [2.16, Nesting of Regions]
4706 // A master region may not be closely nested inside a worksharing,
4707 // atomic, or explicit task region.
4708 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4709 isOpenMPTaskingDirective(ParentRegion);
4710 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
4711 // OpenMP [2.16, Nesting of Regions]
4712 // A critical region may not be nested (closely or otherwise) inside a
4713 // critical region with the same name. Note that this restriction is not
4714 // sufficient to prevent deadlock.
4715 SourceLocation PreviousCriticalLoc;
4716 bool DeadLock = Stack->hasDirective(
4717 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
4718 const DeclarationNameInfo &DNI,
4719 SourceLocation Loc) {
4720 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
4721 PreviousCriticalLoc = Loc;
4722 return true;
4723 }
4724 return false;
4725 },
4726 false /* skip top directive */);
4727 if (DeadLock) {
4728 SemaRef.Diag(StartLoc,
4729 diag::err_omp_prohibited_region_critical_same_name)
4730 << CurrentName.getName();
4731 if (PreviousCriticalLoc.isValid())
4732 SemaRef.Diag(PreviousCriticalLoc,
4733 diag::note_omp_previous_critical_region);
4734 return true;
4735 }
4736 } else if (CurrentRegion == OMPD_barrier) {
4737 // OpenMP [2.16, Nesting of Regions]
4738 // A barrier region may not be closely nested inside a worksharing,
4739 // explicit task, critical, ordered, atomic, or master region.
4740 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4741 isOpenMPTaskingDirective(ParentRegion) ||
4742 ParentRegion == OMPD_master ||
4743 ParentRegion == OMPD_parallel_master ||
4744 ParentRegion == OMPD_critical ||
4745 ParentRegion == OMPD_ordered;
4746 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4747 !isOpenMPParallelDirective(CurrentRegion) &&
4748 !isOpenMPTeamsDirective(CurrentRegion)) {
4749 // OpenMP [2.16, Nesting of Regions]
4750 // A worksharing region may not be closely nested inside a worksharing,
4751 // explicit task, critical, ordered, atomic, or master region.
4752 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4753 isOpenMPTaskingDirective(ParentRegion) ||
4754 ParentRegion == OMPD_master ||
4755 ParentRegion == OMPD_parallel_master ||
4756 ParentRegion == OMPD_critical ||
4757 ParentRegion == OMPD_ordered;
4758 Recommend = ShouldBeInParallelRegion;
4759 } else if (CurrentRegion == OMPD_ordered) {
4760 // OpenMP [2.16, Nesting of Regions]
4761 // An ordered region may not be closely nested inside a critical,
4762 // atomic, or explicit task region.
4763 // An ordered region must be closely nested inside a loop region (or
4764 // parallel loop region) with an ordered clause.
4765 // OpenMP [2.8.1,simd Construct, Restrictions]
4766 // An ordered construct with the simd clause is the only OpenMP construct
4767 // that can appear in the simd region.
4768 NestingProhibited = ParentRegion == OMPD_critical ||
4769 isOpenMPTaskingDirective(ParentRegion) ||
4770 !(isOpenMPSimdDirective(ParentRegion) ||
4771 Stack->isParentOrderedRegion());
4772 Recommend = ShouldBeInOrderedRegion;
4773 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
4774 // OpenMP [2.16, Nesting of Regions]
4775 // If specified, a teams construct must be contained within a target
4776 // construct.
4777 NestingProhibited =
4778 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4779 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4780 ParentRegion != OMPD_target);
4781 OrphanSeen = ParentRegion == OMPD_unknown;
4782 Recommend = ShouldBeInTargetRegion;
4783 } else if (CurrentRegion == OMPD_scan) {
4784 // OpenMP [2.16, Nesting of Regions]
4785 // If specified, a teams construct must be contained within a target
4786 // construct.
4787 NestingProhibited =
4788 SemaRef.LangOpts.OpenMP < 50 ||
4789 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
4790 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
4791 ParentRegion != OMPD_parallel_for_simd);
4792 OrphanSeen = ParentRegion == OMPD_unknown;
4793 Recommend = ShouldBeInLoopSimdRegion;
4794 }
4795 if (!NestingProhibited &&
4796 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
4797 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
4798 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4799 // OpenMP [2.16, Nesting of Regions]
4800 // distribute, parallel, parallel sections, parallel workshare, and the
4801 // parallel loop and parallel loop SIMD constructs are the only OpenMP
4802 // constructs that can be closely nested in the teams region.
4803 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
4804 !isOpenMPDistributeDirective(CurrentRegion);
4805 Recommend = ShouldBeInParallelRegion;
4806 }
4807 if (!NestingProhibited &&
4808 isOpenMPNestingDistributeDirective(CurrentRegion)) {
4809 // OpenMP 4.5 [2.17 Nesting of Regions]
4810 // The region associated with the distribute construct must be strictly
4811 // nested inside a teams region
4812 NestingProhibited =
4813 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
4814 Recommend = ShouldBeInTeamsRegion;
4815 }
4816 if (!NestingProhibited &&
4817 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
4818 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
4819 // OpenMP 4.5 [2.17 Nesting of Regions]
4820 // If a target, target update, target data, target enter data, or
4821 // target exit data construct is encountered during execution of a
4822 // target region, the behavior is unspecified.
4823 NestingProhibited = Stack->hasDirective(
4824 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
4825 SourceLocation) {
4826 if (isOpenMPTargetExecutionDirective(K)) {
4827 OffendingRegion = K;
4828 return true;
4829 }
4830 return false;
4831 },
4832 false /* don't skip top directive */);
4833 CloseNesting = false;
4834 }
4835 if (NestingProhibited) {
4836 if (OrphanSeen) {
4837 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
4838 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
4839 } else {
4840 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4841 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
4842 << Recommend << getOpenMPDirectiveName(CurrentRegion);
4843 }
4844 return true;
4845 }
4846 }
4847 return false;
4848}
4849
4850struct Kind2Unsigned {
4851 using argument_type = OpenMPDirectiveKind;
4852 unsigned operator()(argument_type DK) { return unsigned(DK); }
4853};
4854static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
4855 ArrayRef<OMPClause *> Clauses,
4856 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
4857 bool ErrorFound = false;
4858 unsigned NamedModifiersNumber = 0;
4859 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
4860 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
4861 SmallVector<SourceLocation, 4> NameModifierLoc;
4862 for (const OMPClause *C : Clauses) {
4863 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
4864 // At most one if clause without a directive-name-modifier can appear on
4865 // the directive.
4866 OpenMPDirectiveKind CurNM = IC->getNameModifier();
4867 if (FoundNameModifiers[CurNM]) {
4868 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
4869 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
4870 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
4871 ErrorFound = true;
4872 } else if (CurNM != OMPD_unknown) {
4873 NameModifierLoc.push_back(IC->getNameModifierLoc());
4874 ++NamedModifiersNumber;
4875 }
4876 FoundNameModifiers[CurNM] = IC;
4877 if (CurNM == OMPD_unknown)
4878 continue;
4879 // Check if the specified name modifier is allowed for the current
4880 // directive.
4881 // At most one if clause with the particular directive-name-modifier can
4882 // appear on the directive.
4883 bool MatchFound = false;
4884 for (auto NM : AllowedNameModifiers) {
4885 if (CurNM == NM) {
4886 MatchFound = true;
4887 break;
4888 }
4889 }
4890 if (!MatchFound) {
4891 S.Diag(IC->getNameModifierLoc(),
4892 diag::err_omp_wrong_if_directive_name_modifier)
4893 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
4894 ErrorFound = true;
4895 }
4896 }
4897 }
4898 // If any if clause on the directive includes a directive-name-modifier then
4899 // all if clauses on the directive must include a directive-name-modifier.
4900 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
4901 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
4902 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
4903 diag::err_omp_no_more_if_clause);
4904 } else {
4905 std::string Values;
4906 std::string Sep(", ");
4907 unsigned AllowedCnt = 0;
4908 unsigned TotalAllowedNum =
4909 AllowedNameModifiers.size() - NamedModifiersNumber;
4910 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
4911 ++Cnt) {
4912 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
4913 if (!FoundNameModifiers[NM]) {
4914 Values += "'";
4915 Values += getOpenMPDirectiveName(NM);
4916 Values += "'";
4917 if (AllowedCnt + 2 == TotalAllowedNum)
4918 Values += " or ";
4919 else if (AllowedCnt + 1 != TotalAllowedNum)
4920 Values += Sep;
4921 ++AllowedCnt;
4922 }
4923 }
4924 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
4925 diag::err_omp_unnamed_if_clause)
4926 << (TotalAllowedNum > 1) << Values;
4927 }
4928 for (SourceLocation Loc : NameModifierLoc) {
4929 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
4930 }
4931 ErrorFound = true;
4932 }
4933 return ErrorFound;
4934}
4935
4936static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
4937 SourceLocation &ELoc,
4938 SourceRange &ERange,
4939 bool AllowArraySection) {
4940 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
4941 RefExpr->containsUnexpandedParameterPack())
4942 return std::make_pair(nullptr, true);
4943
4944 // OpenMP [3.1, C/C++]
4945 // A list item is a variable name.
4946 // OpenMP [2.9.3.3, Restrictions, p.1]
4947 // A variable that is part of another variable (as an array or
4948 // structure element) cannot appear in a private clause.
4949 RefExpr = RefExpr->IgnoreParens();
4950 enum {
4951 NoArrayExpr = -1,
4952 ArraySubscript = 0,
4953 OMPArraySection = 1
4954 } IsArrayExpr = NoArrayExpr;
4955 if (AllowArraySection) {
4956 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
4957 Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
4958 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4959 Base = TempASE->getBase()->IgnoreParenImpCasts();
4960 RefExpr = Base;
4961 IsArrayExpr = ArraySubscript;
4962 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
4963 Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
4964 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
4965 Base = TempOASE->getBase()->IgnoreParenImpCasts();
4966 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4967 Base = TempASE->getBase()->IgnoreParenImpCasts();
4968 RefExpr = Base;
4969 IsArrayExpr = OMPArraySection;
4970 }
4971 }
4972 ELoc = RefExpr->getExprLoc();
4973 ERange = RefExpr->getSourceRange();
4974 RefExpr = RefExpr->IgnoreParenImpCasts();
4975 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
4976 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
4977 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
4978 (S.getCurrentThisType().isNull() || !ME ||
4979 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
4980 !isa<FieldDecl>(ME->getMemberDecl()))) {
4981 if (IsArrayExpr != NoArrayExpr) {
4982 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
4983 << ERange;
4984 } else {
4985 S.Diag(ELoc,
4986 AllowArraySection
4987 ? diag::err_omp_expected_var_name_member_expr_or_array_item
4988 : diag::err_omp_expected_var_name_member_expr)
4989 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
4990 }
4991 return std::make_pair(nullptr, false);
4992 }
4993 return std::make_pair(
4994 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
4995}
4996
4997namespace {
4998/// Checks if the allocator is used in uses_allocators clause to be allowed in
4999/// target regions.
5000class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
5001 DSAStackTy *S = nullptr;
5002
5003public:
5004 bool VisitDeclRefExpr(const DeclRefExpr *E) {
5005 return S->isUsesAllocatorsDecl(E->getDecl())
5006 .getValueOr(
5007 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5008 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5009 }
5010 bool VisitStmt(const Stmt *S) {
5011 for (const Stmt *Child : S->children()) {
5012 if (Child && Visit(Child))
5013 return true;
5014 }
5015 return false;
5016 }
5017 explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5018};
5019} // namespace
5020
5021static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
5022 ArrayRef<OMPClause *> Clauses) {
5023 assert(!S.CurContext->isDependentContext() &&
5024 "Expected non-dependent context.");
5025 auto AllocateRange =
5026 llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
5027 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>>
5028 DeclToCopy;
5029 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
5030 return isOpenMPPrivate(C->getClauseKind());
5031 });
5032 for (OMPClause *Cl : PrivateRange) {
5033 MutableArrayRef<Expr *>::iterator I, It, Et;
5034 if (Cl->getClauseKind() == OMPC_private) {
5035 auto *PC = cast<OMPPrivateClause>(Cl);
5036 I = PC->private_copies().begin();
5037 It = PC->varlist_begin();
5038 Et = PC->varlist_end();
5039 } else if (Cl->getClauseKind() == OMPC_firstprivate) {
5040 auto *PC = cast<OMPFirstprivateClause>(Cl);
5041 I = PC->private_copies().begin();
5042 It = PC->varlist_begin();
5043 Et = PC->varlist_end();
5044 } else if (Cl->getClauseKind() == OMPC_lastprivate) {
5045 auto *PC = cast<OMPLastprivateClause>(Cl);
5046 I = PC->private_copies().begin();
5047 It = PC->varlist_begin();
5048 Et = PC->varlist_end();
5049 } else if (Cl->getClauseKind() == OMPC_linear) {
5050 auto *PC = cast<OMPLinearClause>(Cl);
5051 I = PC->privates().begin();
5052 It = PC->varlist_begin();
5053 Et = PC->varlist_end();
5054 } else if (Cl->getClauseKind() == OMPC_reduction) {
5055 auto *PC = cast<OMPReductionClause>(Cl);
5056 I = PC->privates().begin();
5057 It = PC->varlist_begin();
5058 Et = PC->varlist_end();
5059 } else if (Cl->getClauseKind() == OMPC_task_reduction) {
5060 auto *PC = cast<OMPTaskReductionClause>(Cl);
5061 I = PC->privates().begin();
5062 It = PC->varlist_begin();
5063 Et = PC->varlist_end();
5064 } else if (Cl->getClauseKind() == OMPC_in_reduction) {
5065 auto *PC = cast<OMPInReductionClause>(Cl);
5066 I = PC->privates().begin();
5067 It = PC->varlist_begin();
5068 Et = PC->varlist_end();
5069 } else {
5070 llvm_unreachable("Expected private clause.");
5071 }
5072 for (Expr *E : llvm::make_range(It, Et)) {
5073 if (!*I) {
5074 ++I;
5075 continue;
5076 }
5077 SourceLocation ELoc;
5078 SourceRange ERange;
5079 Expr *SimpleRefExpr = E;
5080 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
5081 /*AllowArraySection=*/true);
5082 DeclToCopy.try_emplace(Res.first,
5083 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5084 ++I;
5085 }
5086 }
5087 for (OMPClause *C : AllocateRange) {
5088 auto *AC = cast<OMPAllocateClause>(C);
5089 if (S.getLangOpts().OpenMP >= 50 &&
5090 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
5091 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
5092 AC->getAllocator()) {
5093 Expr *Allocator = AC->getAllocator();
5094 // OpenMP, 2.12.5 target Construct
5095 // Memory allocators that do not appear in a uses_allocators clause cannot
5096 // appear as an allocator in an allocate clause or be used in the target
5097 // region unless a requires directive with the dynamic_allocators clause
5098 // is present in the same compilation unit.
5099 AllocatorChecker Checker(Stack);
5100 if (Checker.Visit(Allocator))
5101 S.Diag(Allocator->getExprLoc(),
5102 diag::err_omp_allocator_not_in_uses_allocators)
5103 << Allocator->getSourceRange();
5104 }
5105 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5106 getAllocatorKind(S, Stack, AC->getAllocator());
5107 // OpenMP, 2.11.4 allocate Clause, Restrictions.
5108 // For task, taskloop or target directives, allocation requests to memory
5109 // allocators with the trait access set to thread result in unspecified
5110 // behavior.
5111 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5112 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5113 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5114 S.Diag(AC->getAllocator()->getExprLoc(),
5115 diag::warn_omp_allocate_thread_on_task_target_directive)
5116 << getOpenMPDirectiveName(Stack->getCurrentDirective());
5117 }
5118 for (Expr *E : AC->varlists()) {
5119 SourceLocation ELoc;
5120 SourceRange ERange;
5121 Expr *SimpleRefExpr = E;
5122 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5123 ValueDecl *VD = Res.first;
5124 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5125 if (!isOpenMPPrivate(Data.CKind)) {
5126 S.Diag(E->getExprLoc(),
5127 diag::err_omp_expected_private_copy_for_allocate);
5128 continue;
5129 }
5130 VarDecl *PrivateVD = DeclToCopy[VD];
5131 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5132 AllocatorKind, AC->getAllocator()))
5133 continue;
5134 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5135 E->getSourceRange());
5136 }
5137 }
5138}
5139
5140StmtResult Sema::ActOnOpenMPExecutableDirective(
5141 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
5142 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
5143 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5144 StmtResult Res = StmtError();
5145 // First check CancelRegion which is then used in checkNestingOfRegions.
5146 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
5147 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
5148 StartLoc))
5149 return StmtError();
5150
5151 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
5152 VarsWithInheritedDSAType VarsWithInheritedDSA;
5153 bool ErrorFound = false;
5154 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
5155 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
5156 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master) {
5157 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5158
5159 // Check default data sharing attributes for referenced variables.
5160 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
5161 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
5162 Stmt *S = AStmt;
5163 while (--ThisCaptureLevel >= 0)
5164 S = cast<CapturedStmt>(S)->getCapturedStmt();
5165 DSAChecker.Visit(S);
5166 if (!isOpenMPTargetDataManagementDirective(Kind) &&
5167 !isOpenMPTaskingDirective(Kind)) {
5168 // Visit subcaptures to generate implicit clauses for captured vars.
5169 auto *CS = cast<CapturedStmt>(AStmt);
5170 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
5171 getOpenMPCaptureRegions(CaptureRegions, Kind);
5172 // Ignore outer tasking regions for target directives.
5173 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
5174 CS = cast<CapturedStmt>(CS->getCapturedStmt());
5175 DSAChecker.visitSubCaptures(CS);
5176 }
5177 if (DSAChecker.isErrorFound())
5178 return StmtError();
5179 // Generate list of implicitly defined firstprivate variables.
5180 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
5181
5182 SmallVector<Expr *, 4> ImplicitFirstprivates(
5183 DSAChecker.getImplicitFirstprivate().begin(),
5184 DSAChecker.getImplicitFirstprivate().end());
5185 const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
5186 SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
5187 SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
5188 ImplicitMapModifiers[DefaultmapKindNum];
5189 SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
5190 ImplicitMapModifiersLoc[DefaultmapKindNum];
5191 // Get the original location of present modifier from Defaultmap clause.
5192 SourceLocation PresentModifierLocs[DefaultmapKindNum];
5193 for (OMPClause *C : Clauses) {
5194 if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C))
5195 if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
5196 PresentModifierLocs[DMC->getDefaultmapKind()] =
5197 DMC->getDefaultmapModifierLoc();
5198 }
5199 for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
5200 auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC);
5201 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
5202 ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap(
5203 Kind, static_cast<OpenMPMapClauseKind>(I));
5204 ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
5205 }
5206 ArrayRef<OpenMPMapModifierKind> ImplicitModifier =
5207 DSAChecker.getImplicitMapModifier(Kind);
5208 ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
5209 ImplicitModifier.end());
5210 std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
5211 ImplicitModifier.size(), PresentModifierLocs[VC]);
5212 }
5213 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
5214 for (OMPClause *C : Clauses) {
5215 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
5216 for (Expr *E : IRC->taskgroup_descriptors())
5217 if (E)
5218 ImplicitFirstprivates.emplace_back(E);
5219 }
5220 // OpenMP 5.0, 2.10.1 task Construct
5221 // [detach clause]... The event-handle will be considered as if it was
5222 // specified on a firstprivate clause.
5223 if (auto *DC = dyn_cast<OMPDetachClause>(C))
5224 ImplicitFirstprivates.push_back(DC->getEventHandler());
5225 }
5226 if (!ImplicitFirstprivates.empty()) {
5227 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
5228 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
5229 SourceLocation())) {
5230 ClausesWithImplicit.push_back(Implicit);
5231 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
5232 ImplicitFirstprivates.size();
5233 } else {
5234 ErrorFound = true;
5235 }
5236 }
5237 for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
5238 int ClauseKindCnt = -1;
5239 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) {
5240 ++ClauseKindCnt;
5241 if (ImplicitMap.empty())
5242 continue;
5243 CXXScopeSpec MapperIdScopeSpec;
5244 DeclarationNameInfo MapperId;
5245 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
5246 if (OMPClause *Implicit = ActOnOpenMPMapClause(
5247 ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
5248 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true,
5249 SourceLocation(), SourceLocation(), ImplicitMap,
5250 OMPVarListLocTy())) {
5251 ClausesWithImplicit.emplace_back(Implicit);
5252 ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() !=
5253 ImplicitMap.size();
5254 } else {
5255 ErrorFound = true;
5256 }
5257 }
5258 }
5259 }
5260
5261 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
5262 switch (Kind) {
5263 case OMPD_parallel:
5264 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
5265 EndLoc);
5266 AllowedNameModifiers.push_back(OMPD_parallel);
5267 break;
5268 case OMPD_simd:
5269 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5270 VarsWithInheritedDSA);
5271 if (LangOpts.OpenMP >= 50)
5272 AllowedNameModifiers.push_back(OMPD_simd);
5273 break;
5274 case OMPD_for:
5275 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5276 VarsWithInheritedDSA);
5277 break;
5278 case OMPD_for_simd:
5279 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5280 EndLoc, VarsWithInheritedDSA);
5281 if (LangOpts.OpenMP >= 50)
5282 AllowedNameModifiers.push_back(OMPD_simd);
5283 break;
5284 case OMPD_sections:
5285 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
5286 EndLoc);
5287 break;
5288 case OMPD_section:
5289 assert(ClausesWithImplicit.empty() &&
5290 "No clauses are allowed for 'omp section' directive");
5291 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
5292 break;
5293 case OMPD_single:
5294 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
5295 EndLoc);
5296 break;
5297 case OMPD_master:
5298 assert(ClausesWithImplicit.empty() &&
5299 "No clauses are allowed for 'omp master' directive");
5300 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
5301 break;
5302 case OMPD_critical:
5303 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
5304 StartLoc, EndLoc);
5305 break;
5306 case OMPD_parallel_for:
5307 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
5308 EndLoc, VarsWithInheritedDSA);
5309 AllowedNameModifiers.push_back(OMPD_parallel);
5310 break;
5311 case OMPD_parallel_for_simd:
5312 Res = ActOnOpenMPParallelForSimdDirective(
5313 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5314 AllowedNameModifiers.push_back(OMPD_parallel);
5315 if (LangOpts.OpenMP >= 50)
5316 AllowedNameModifiers.push_back(OMPD_simd);
5317 break;
5318 case OMPD_parallel_master:
5319 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
5320 StartLoc, EndLoc);
5321 AllowedNameModifiers.push_back(OMPD_parallel);
5322 break;
5323 case OMPD_parallel_sections:
5324 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
5325 StartLoc, EndLoc);
5326 AllowedNameModifiers.push_back(OMPD_parallel);
5327 break;
5328 case OMPD_task:
5329 Res =
5330 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5331 AllowedNameModifiers.push_back(OMPD_task);
5332 break;
5333 case OMPD_taskyield:
5334 assert(ClausesWithImplicit.empty() &&
5335 "No clauses are allowed for 'omp taskyield' directive");
5336 assert(AStmt == nullptr &&
5337 "No associated statement allowed for 'omp taskyield' directive");
5338 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
5339 break;
5340 case OMPD_barrier:
5341 assert(ClausesWithImplicit.empty() &&
5342 "No clauses are allowed for 'omp barrier' directive");
5343 assert(AStmt == nullptr &&
5344 "No associated statement allowed for 'omp barrier' directive");
5345 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
5346 break;
5347 case OMPD_taskwait:
5348 assert(ClausesWithImplicit.empty() &&
5349 "No clauses are allowed for 'omp taskwait' directive");
5350 assert(AStmt == nullptr &&
5351 "No associated statement allowed for 'omp taskwait' directive");
5352 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
5353 break;
5354 case OMPD_taskgroup:
5355 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
5356 EndLoc);
5357 break;
5358 case OMPD_flush:
5359 assert(AStmt == nullptr &&
5360 "No associated statement allowed for 'omp flush' directive");
5361 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
5362 break;
5363 case OMPD_depobj:
5364 assert(AStmt == nullptr &&
5365 "No associated statement allowed for 'omp depobj' directive");
5366 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
5367 break;
5368 case OMPD_scan:
5369 assert(AStmt == nullptr &&
5370 "No associated statement allowed for 'omp scan' directive");
5371 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
5372 break;
5373 case OMPD_ordered:
5374 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
5375 EndLoc);
5376 break;
5377 case OMPD_atomic:
5378 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
5379 EndLoc);
5380 break;
5381 case OMPD_teams:
5382 Res =
5383 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5384 break;
5385 case OMPD_target:
5386 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
5387 EndLoc);
5388 AllowedNameModifiers.push_back(OMPD_target);
5389 break;
5390 case OMPD_target_parallel:
5391 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
5392 StartLoc, EndLoc);
5393 AllowedNameModifiers.push_back(OMPD_target);
5394 AllowedNameModifiers.push_back(OMPD_parallel);
5395 break;
5396 case OMPD_target_parallel_for:
5397 Res = ActOnOpenMPTargetParallelForDirective(
5398 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5399 AllowedNameModifiers.push_back(OMPD_target);
5400 AllowedNameModifiers.push_back(OMPD_parallel);
5401 break;
5402 case OMPD_cancellation_point:
5403 assert(ClausesWithImplicit.empty() &&
5404 "No clauses are allowed for 'omp cancellation point' directive");
5405 assert(AStmt == nullptr && "No associated statement allowed for 'omp "
5406 "cancellation point' directive");
5407 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
5408 break;
5409 case OMPD_cancel:
5410 assert(AStmt == nullptr &&
5411 "No associated statement allowed for 'omp cancel' directive");
5412 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
5413 CancelRegion);
5414 AllowedNameModifiers.push_back(OMPD_cancel);
5415 break;
5416 case OMPD_target_data:
5417 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
5418 EndLoc);
5419 AllowedNameModifiers.push_back(OMPD_target_data);
5420 break;
5421 case OMPD_target_enter_data:
5422 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
5423 EndLoc, AStmt);
5424 AllowedNameModifiers.push_back(OMPD_target_enter_data);
5425 break;
5426 case OMPD_target_exit_data:
5427 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
5428 EndLoc, AStmt);
5429 AllowedNameModifiers.push_back(OMPD_target_exit_data);
5430 break;
5431 case OMPD_taskloop:
5432 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
5433 EndLoc, VarsWithInheritedDSA);
5434 AllowedNameModifiers.push_back(OMPD_taskloop);
5435 break;
5436 case OMPD_taskloop_simd:
5437 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5438 EndLoc, VarsWithInheritedDSA);
5439 AllowedNameModifiers.push_back(OMPD_taskloop);
5440 if (LangOpts.OpenMP >= 50)
5441 AllowedNameModifiers.push_back(OMPD_simd);
5442 break;
5443 case OMPD_master_taskloop:
5444 Res = ActOnOpenMPMasterTaskLoopDirective(
5445 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5446 AllowedNameModifiers.push_back(OMPD_taskloop);
5447 break;
5448 case OMPD_master_taskloop_simd:
5449 Res = ActOnOpenMPMasterTaskLoopSimdDirective(
5450 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5451 AllowedNameModifiers.push_back(OMPD_taskloop);
5452 if (LangOpts.OpenMP >= 50)
5453 AllowedNameModifiers.push_back(OMPD_simd);
5454 break;
5455 case OMPD_parallel_master_taskloop:
5456 Res = ActOnOpenMPParallelMasterTaskLoopDirective(
5457 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5458 AllowedNameModifiers.push_back(OMPD_taskloop);
5459 AllowedNameModifiers.push_back(OMPD_parallel);
5460 break;
5461 case OMPD_parallel_master_taskloop_simd:
5462 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
5463 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5464 AllowedNameModifiers.push_back(OMPD_taskloop);
5465 AllowedNameModifiers.push_back(OMPD_parallel);
5466 if (LangOpts.OpenMP >= 50)
5467 AllowedNameModifiers.push_back(OMPD_simd);
5468 break;
5469 case OMPD_distribute:
5470 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
5471 EndLoc, VarsWithInheritedDSA);
5472 break;
5473 case OMPD_target_update:
5474 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
5475 EndLoc, AStmt);
5476 AllowedNameModifiers.push_back(OMPD_target_update);
5477 break;
5478 case OMPD_distribute_parallel_for:
5479 Res = ActOnOpenMPDistributeParallelForDirective(
5480 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5481 AllowedNameModifiers.push_back(OMPD_parallel);
5482 break;
5483 case OMPD_distribute_parallel_for_simd:
5484 Res = ActOnOpenMPDistributeParallelForSimdDirective(
5485 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5486 AllowedNameModifiers.push_back(OMPD_parallel);
5487 if (LangOpts.OpenMP >= 50)
5488 AllowedNameModifiers.push_back(OMPD_simd);
5489 break;
5490 case OMPD_distribute_simd:
5491 Res = ActOnOpenMPDistributeSimdDirective(
5492 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5493 if (LangOpts.OpenMP >= 50)
5494 AllowedNameModifiers.push_back(OMPD_simd);
5495 break;
5496 case OMPD_target_parallel_for_simd:
5497 Res = ActOnOpenMPTargetParallelForSimdDirective(
5498 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5499 AllowedNameModifiers.push_back(OMPD_target);
5500 AllowedNameModifiers.push_back(OMPD_parallel);
5501 if (LangOpts.OpenMP >= 50)
5502 AllowedNameModifiers.push_back(OMPD_simd);
5503 break;
5504 case OMPD_target_simd:
5505 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5506 EndLoc, VarsWithInheritedDSA);
5507 AllowedNameModifiers.push_back(OMPD_target);
5508 if (LangOpts.OpenMP >= 50)
5509 AllowedNameModifiers.push_back(OMPD_simd);
5510 break;
5511 case OMPD_teams_distribute:
5512 Res = ActOnOpenMPTeamsDistributeDirective(
5513 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5514 break;
5515 case OMPD_teams_distribute_simd:
5516 Res = ActOnOpenMPTeamsDistributeSimdDirective(
5517 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5518 if (LangOpts.OpenMP >= 50)
5519 AllowedNameModifiers.push_back(OMPD_simd);
5520 break;
5521 case OMPD_teams_distribute_parallel_for_simd:
5522 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
5523 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5524 AllowedNameModifiers.push_back(OMPD_parallel);
5525 if (LangOpts.OpenMP >= 50)
5526 AllowedNameModifiers.push_back(OMPD_simd);
5527 break;
5528 case OMPD_teams_distribute_parallel_for:
5529 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
5530 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5531 AllowedNameModifiers.push_back(OMPD_parallel);
5532 break;
5533 case OMPD_target_teams:
5534 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
5535 EndLoc);
5536 AllowedNameModifiers.push_back(OMPD_target);
5537 break;
5538 case OMPD_target_teams_distribute:
5539 Res = ActOnOpenMPTargetTeamsDistributeDirective(
5540 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5541 AllowedNameModifiers.push_back(OMPD_target);
5542 break;
5543 case OMPD_target_teams_distribute_parallel_for:
5544 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
5545 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5546 AllowedNameModifiers.push_back(OMPD_target);
5547 AllowedNameModifiers.push_back(OMPD_parallel);
5548 break;
5549 case OMPD_target_teams_distribute_parallel_for_simd:
5550 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
5551 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5552 AllowedNameModifiers.push_back(OMPD_target);
5553 AllowedNameModifiers.push_back(OMPD_parallel);
5554 if (LangOpts.OpenMP >= 50)
5555 AllowedNameModifiers.push_back(OMPD_simd);
5556 break;
5557 case OMPD_target_teams_distribute_simd:
5558 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
5559 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5560 AllowedNameModifiers.push_back(OMPD_target);
5561 if (LangOpts.OpenMP >= 50)
5562 AllowedNameModifiers.push_back(OMPD_simd);
5563 break;
5564 case OMPD_declare_target:
5565 case OMPD_end_declare_target:
5566 case OMPD_threadprivate:
5567 case OMPD_allocate:
5568 case OMPD_declare_reduction:
5569 case OMPD_declare_mapper:
5570 case OMPD_declare_simd:
5571 case OMPD_requires:
5572 case OMPD_declare_variant:
5573 case OMPD_begin_declare_variant:
5574 case OMPD_end_declare_variant:
5575 llvm_unreachable("OpenMP Directive is not allowed");
5576 case OMPD_unknown:
5577 default:
5578 llvm_unreachable("Unknown OpenMP directive");
5579 }
5580
5581 ErrorFound = Res.isInvalid() || ErrorFound;
5582
5583 // Check variables in the clauses if default(none) or
5584 // default(firstprivate) was specified.
5585 if (DSAStack->getDefaultDSA() == DSA_none ||
5586 DSAStack->getDefaultDSA() == DSA_firstprivate) {
5587 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
5588 for (OMPClause *C : Clauses) {
5589 switch (C->getClauseKind()) {
5590 case OMPC_num_threads:
5591 case OMPC_dist_schedule:
5592 // Do not analyse if no parent teams directive.
5593 if (isOpenMPTeamsDirective(Kind))
5594 break;
5595 continue;
5596 case OMPC_if:
5597 if (isOpenMPTeamsDirective(Kind) &&
5598 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
5599 break;
5600 if (isOpenMPParallelDirective(Kind) &&
5601 isOpenMPTaskLoopDirective(Kind) &&
5602 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
5603 break;
5604 continue;
5605 case OMPC_schedule:
5606 case OMPC_detach:
5607 break;
5608 case OMPC_grainsize:
5609 case OMPC_num_tasks:
5610 case OMPC_final:
5611 case OMPC_priority:
5612 // Do not analyze if no parent parallel directive.
5613 if (isOpenMPParallelDirective(Kind))
5614 break;
5615 continue;
5616 case OMPC_ordered:
5617 case OMPC_device:
5618 case OMPC_num_teams:
5619 case OMPC_thread_limit:
5620 case OMPC_hint:
5621 case OMPC_collapse:
5622 case OMPC_safelen:
5623 case OMPC_simdlen:
5624 case OMPC_default:
5625 case OMPC_proc_bind:
5626 case OMPC_private:
5627 case OMPC_firstprivate:
5628 case OMPC_lastprivate:
5629 case OMPC_shared:
5630 case OMPC_reduction:
5631 case OMPC_task_reduction:
5632 case OMPC_in_reduction:
5633 case OMPC_linear:
5634 case OMPC_aligned:
5635 case OMPC_copyin:
5636 case OMPC_copyprivate:
5637 case OMPC_nowait:
5638 case OMPC_untied:
5639 case OMPC_mergeable:
5640 case OMPC_allocate:
5641 case OMPC_read:
5642 case OMPC_write:
5643 case OMPC_update:
5644 case OMPC_capture:
5645 case OMPC_seq_cst:
5646 case OMPC_acq_rel:
5647 case OMPC_acquire:
5648 case OMPC_release:
5649 case OMPC_relaxed:
5650 case OMPC_depend:
5651 case OMPC_threads:
5652 case OMPC_simd:
5653 case OMPC_map:
5654 case OMPC_nogroup:
5655 case OMPC_defaultmap:
5656 case OMPC_to:
5657 case OMPC_from:
5658 case OMPC_use_device_ptr:
5659 case OMPC_use_device_addr:
5660 case OMPC_is_device_ptr:
5661 case OMPC_nontemporal:
5662 case OMPC_order:
5663 case OMPC_destroy:
5664 case OMPC_inclusive:
5665 case OMPC_exclusive:
5666 case OMPC_uses_allocators:
5667 case OMPC_affinity:
5668 continue;
5669 case OMPC_allocator:
5670 case OMPC_flush:
5671 case OMPC_depobj:
5672 case OMPC_threadprivate:
5673 case OMPC_uniform:
5674 case OMPC_unknown:
5675 case OMPC_unified_address:
5676 case OMPC_unified_shared_memory:
5677 case OMPC_reverse_offload:
5678 case OMPC_dynamic_allocators:
5679 case OMPC_atomic_default_mem_order:
5680 case OMPC_device_type:
5681 case OMPC_match:
5682 default:
5683 llvm_unreachable("Unexpected clause");
5684 }
5685 for (Stmt *CC : C->children()) {
5686 if (CC)
5687 DSAChecker.Visit(CC);
5688 }
5689 }
5690 for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
5691 VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
5692 }
5693 for (const auto &P : VarsWithInheritedDSA) {
5694 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
5695 continue;
5696 ErrorFound = true;
5697 if (DSAStack->getDefaultDSA() == DSA_none ||
5698 DSAStack->getDefaultDSA() == DSA_firstprivate) {
5699 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
5700 << P.first << P.second->getSourceRange();
5701 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
5702 } else if (getLangOpts().OpenMP >= 50) {
5703 Diag(P.second->getExprLoc(),
5704 diag::err_omp_defaultmap_no_attr_for_variable)
5705 << P.first << P.second->getSourceRange();
5706 Diag(DSAStack->getDefaultDSALocation(),
5707 diag::note_omp_defaultmap_attr_none);
5708 }
5709 }
5710
5711 if (!AllowedNameModifiers.empty())
5712 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
5713 ErrorFound;
5714
5715 if (ErrorFound)
5716 return StmtError();
5717
5718 if (!CurContext->isDependentContext() &&
5719 isOpenMPTargetExecutionDirective(Kind) &&
5720 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
5721 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
5722 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
5723 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
5724 // Register target to DSA Stack.
5725 DSAStack->addTargetDirLocation(StartLoc);
5726 }
5727
5728 return Res;
5729}
5730
5731Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
5732 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
5733 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
5734 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
5735 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
5736 assert(Aligneds.size() == Alignments.size());
5737 assert(Linears.size() == LinModifiers.size());
5738 assert(Linears.size() == Steps.size());
5739 if (!DG || DG.get().isNull())
5740 return DeclGroupPtrTy();
5741
5742 const int SimdId = 0;
5743 if (!DG.get().isSingleDecl()) {
5744 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
5745 << SimdId;
5746 return DG;
5747 }
5748 Decl *ADecl = DG.get().getSingleDecl();
5749 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
5750 ADecl = FTD->getTemplatedDecl();
5751
5752 auto *FD = dyn_cast<FunctionDecl>(ADecl);
5753 if (!FD) {
5754 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
5755 return DeclGroupPtrTy();
5756 }
5757
5758 // OpenMP [2.8.2, declare simd construct, Description]
5759 // The parameter of the simdlen clause must be a constant positive integer
5760 // expression.
5761 ExprResult SL;
5762 if (Simdlen)
5763 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
5764 // OpenMP [2.8.2, declare simd construct, Description]
5765 // The special this pointer can be used as if was one of the arguments to the
5766 // function in any of the linear, aligned, or uniform clauses.
5767 // The uniform clause declares one or more arguments to have an invariant
5768 // value for all concurrent invocations of the function in the execution of a
5769 // single SIMD loop.
5770 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
5771 const Expr *UniformedLinearThis = nullptr;
5772 for (const Expr *E : Uniforms) {
5773 E = E->IgnoreParenImpCasts();
5774 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5775 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
5776 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5777 FD->getParamDecl(PVD->getFunctionScopeIndex())
5778 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
5779 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
5780 continue;
5781 }
5782 if (isa<CXXThisExpr>(E)) {
5783 UniformedLinearThis = E;
5784 continue;
5785 }
5786 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5787 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5788 }
5789 // OpenMP [2.8.2, declare simd construct, Description]
5790 // The aligned clause declares that the object to which each list item points
5791 // is aligned to the number of bytes expressed in the optional parameter of
5792 // the aligned clause.
5793 // The special this pointer can be used as if was one of the arguments to the
5794 // function in any of the linear, aligned, or uniform clauses.
5795 // The type of list items appearing in the aligned clause must be array,
5796 // pointer, reference to array, or reference to pointer.
5797 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
5798 const Expr *AlignedThis = nullptr;
5799 for (const Expr *E : Aligneds) {
5800 E = E->IgnoreParenImpCasts();
5801 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5802 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5803 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5804 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5805 FD->getParamDecl(PVD->getFunctionScopeIndex())
5806 ->getCanonicalDecl() == CanonPVD) {
5807 // OpenMP [2.8.1, simd construct, Restrictions]
5808 // A list-item cannot appear in more than one aligned clause.
5809 if (AlignedArgs.count(CanonPVD) > 0) {
5810 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
5811 << 1 << getOpenMPClauseName(OMPC_aligned)
5812 << E->getSourceRange();
5813 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
5814 diag::note_omp_explicit_dsa)
5815 << getOpenMPClauseName(OMPC_aligned);
5816 continue;
5817 }
5818 AlignedArgs[CanonPVD] = E;
5819 QualType QTy = PVD->getType()
5820 .getNonReferenceType()
5821 .getUnqualifiedType()
5822 .getCanonicalType();
5823 const Type *Ty = QTy.getTypePtrOrNull();
5824 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
5825 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
5826 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
5827 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
5828 }
5829 continue;
5830 }
5831 }
5832 if (isa<CXXThisExpr>(E)) {
5833 if (AlignedThis) {
5834 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
5835 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
5836 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
5837 << getOpenMPClauseName(OMPC_aligned);
5838 }
5839 AlignedThis = E;
5840 continue;
5841 }
5842 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5843 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5844 }
5845 // The optional parameter of the aligned clause, alignment, must be a constant
5846 // positive integer expression. If no optional parameter is specified,
5847 // implementation-defined default alignments for SIMD instructions on the
5848 // target platforms are assumed.
5849 SmallVector<const Expr *, 4> NewAligns;
5850 for (Expr *E : Alignments) {
5851 ExprResult Align;
5852 if (E)
5853 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
5854 NewAligns.push_back(Align.get());
5855 }
5856 // OpenMP [2.8.2, declare simd construct, Description]
5857 // The linear clause declares one or more list items to be private to a SIMD
5858 // lane and to have a linear relationship with respect to the iteration space
5859 // of a loop.
5860 // The special this pointer can be used as if was one of the arguments to the
5861 // function in any of the linear, aligned, or uniform clauses.
5862 // When a linear-step expression is specified in a linear clause it must be
5863 // either a constant integer expression or an integer-typed parameter that is
5864 // specified in a uniform clause on the directive.
5865 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
5866 const bool IsUniformedThis = UniformedLinearThis != nullptr;
5867 auto MI = LinModifiers.begin();
5868 for (const Expr *E : Linears) {
5869 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
5870 ++MI;
5871 E = E->IgnoreParenImpCasts();
5872 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5873 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5874 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5875 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5876 FD->getParamDecl(PVD->getFunctionScopeIndex())
5877 ->getCanonicalDecl() == CanonPVD) {
5878 // OpenMP [2.15.3.7, linear Clause, Restrictions]
5879 // A list-item cannot appear in more than one linear clause.
5880 if (LinearArgs.count(CanonPVD) > 0) {
5881 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5882 << getOpenMPClauseName(OMPC_linear)
5883 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
5884 Diag(LinearArgs[CanonPVD]->getExprLoc(),
5885 diag::note_omp_explicit_dsa)
5886 << getOpenMPClauseName(OMPC_linear);
5887 continue;
5888 }
5889 // Each argument can appear in at most one uniform or linear clause.
5890 if (UniformedArgs.count(CanonPVD) > 0) {
5891 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5892 << getOpenMPClauseName(OMPC_linear)
5893 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
5894 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
5895 diag::note_omp_explicit_dsa)
5896 << getOpenMPClauseName(OMPC_uniform);
5897 continue;
5898 }
5899 LinearArgs[CanonPVD] = E;
5900 if (E->isValueDependent() || E->isTypeDependent() ||
5901 E->isInstantiationDependent() ||
5902 E->containsUnexpandedParameterPack())
5903 continue;
5904 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
5905 PVD->getOriginalType(),
5906 /*IsDeclareSimd=*/true);
5907 continue;
5908 }
5909 }
5910 if (isa<CXXThisExpr>(E)) {
5911 if (UniformedLinearThis) {
5912 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5913 << getOpenMPClauseName(OMPC_linear)
5914 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
5915 << E->getSourceRange();
5916 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
5917 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
5918 : OMPC_linear);
5919 continue;
5920 }
5921 UniformedLinearThis = E;
5922 if (E->isValueDependent() || E->isTypeDependent() ||
5923 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
5924 continue;
5925 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
5926 E->getType(), /*IsDeclareSimd=*/true);
5927 continue;
5928 }
5929 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5930 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5931 }
5932 Expr *Step = nullptr;
5933 Expr *NewStep = nullptr;
5934 SmallVector<Expr *, 4> NewSteps;
5935 for (Expr *E : Steps) {
5936 // Skip the same step expression, it was checked already.
5937 if (Step == E || !E) {
5938 NewSteps.push_back(E ? NewStep : nullptr);
5939 continue;
5940 }
5941 Step = E;
5942 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
5943 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5944 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5945 if (UniformedArgs.count(CanonPVD) == 0) {
5946 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
5947 << Step->getSourceRange();
5948 } else if (E->isValueDependent() || E->isTypeDependent() ||
5949 E->isInstantiationDependent() ||
5950 E->containsUnexpandedParameterPack() ||
5951 CanonPVD->getType()->hasIntegerRepresentation()) {
5952 NewSteps.push_back(Step);
5953 } else {
5954 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
5955 << Step->getSourceRange();
5956 }
5957 continue;
5958 }
5959 NewStep = Step;
5960 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
5961 !Step->isInstantiationDependent() &&
5962 !Step->containsUnexpandedParameterPack()) {
5963 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
5964 .get();
5965 if (NewStep)
5966 NewStep =
5967 VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get();
5968 }
5969 NewSteps.push_back(NewStep);
5970 }
5971 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
5972 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
5973 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
5974 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
5975 const_cast<Expr **>(Linears.data()), Linears.size(),
5976 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
5977 NewSteps.data(), NewSteps.size(), SR);
5978 ADecl->addAttr(NewAttr);
5979 return DG;
5980}
5981
5982static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
5983 QualType NewType) {
5984 assert(NewType->isFunctionProtoType() &&
5985 "Expected function type with prototype.");
5986 assert(FD->getType()->isFunctionNoProtoType() &&
5987 "Expected function with type with no prototype.");
5988 assert(FDWithProto->getType()->isFunctionProtoType() &&
5989 "Expected function with prototype.");
5990 // Synthesize parameters with the same types.
5991 FD->setType(NewType);
5992 SmallVector<ParmVarDecl *, 16> Params;
5993 for (const ParmVarDecl *P : FDWithProto->parameters()) {
5994 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
5995 SourceLocation(), nullptr, P->getType(),
5996 /*TInfo=*/nullptr, SC_None, nullptr);
5997 Param->setScopeInfo(0, Params.size());
5998 Param->setImplicit();
5999 Params.push_back(Param);
6000 }
6001
6002 FD->setParams(Params);
6003}
6004
6005void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) {
6006 if (D->isInvalidDecl())
6007 return;
6008 FunctionDecl *FD = nullptr;
6009 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6010 FD = UTemplDecl->getTemplatedDecl();
6011 else
6012 FD = cast<FunctionDecl>(D);
6013 assert(FD && "Expected a function declaration!");
6014
6015 // If we are intantiating templates we do *not* apply scoped assumptions but
6016 // only global ones. We apply scoped assumption to the template definition
6017 // though.
6018 if (!inTemplateInstantiation()) {
6019 for (AssumptionAttr *AA : OMPAssumeScoped)
6020 FD->addAttr(AA);
6021 }
6022 for (AssumptionAttr *AA : OMPAssumeGlobal)
6023 FD->addAttr(AA);
6024}
6025
6026Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
6027 : TI(&TI), NameSuffix(TI.getMangledName()) {}
6028
6029void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
6030 Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
6031 SmallVectorImpl<FunctionDecl *> &Bases) {
6032 if (!D.getIdentifier())
6033 return;
6034
6035 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6036
6037 // Template specialization is an extension, check if we do it.
6038 bool IsTemplated = !TemplateParamLists.empty();
6039 if (IsTemplated &
6040 !DVScope.TI->isExtensionActive(
6041 llvm::omp::TraitProperty::implementation_extension_allow_templates))
6042 return;
6043
6044 IdentifierInfo *BaseII = D.getIdentifier();
6045 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
6046 LookupOrdinaryName);
6047 LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
6048
6049 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
6050 QualType FType = TInfo->getType();
6051
6052 bool IsConstexpr =
6053 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr;
6054 bool IsConsteval =
6055 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval;
6056
6057 for (auto *Candidate : Lookup) {
6058 auto *CandidateDecl = Candidate->getUnderlyingDecl();
6059 FunctionDecl *UDecl = nullptr;
6060 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl))
6061 UDecl = cast<FunctionTemplateDecl>(CandidateDecl)->getTemplatedDecl();
6062 else if (!IsTemplated)
6063 UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
6064 if (!UDecl)
6065 continue;
6066
6067 // Don't specialize constexpr/consteval functions with
6068 // non-constexpr/consteval functions.
6069 if (UDecl->isConstexpr() && !IsConstexpr)
6070 continue;
6071 if (UDecl->isConsteval() && !IsConsteval)
6072 continue;
6073
6074 QualType UDeclTy = UDecl->getType();
6075 if (!UDeclTy->isDependentType()) {
6076 QualType NewType = Context.mergeFunctionTypes(
6077 FType, UDeclTy, /* OfBlockPointer */ false,
6078 /* Unqualified */ false, /* AllowCXX */ true);
6079 if (NewType.isNull())
6080 continue;
6081 }
6082
6083 // Found a base!
6084 Bases.push_back(UDecl);
6085 }
6086
6087 bool UseImplicitBase = !DVScope.TI->isExtensionActive(
6088 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
6089 // If no base was found we create a declaration that we use as base.
6090 if (Bases.empty() && UseImplicitBase) {
6091 D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
6092 Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
6093 BaseD->setImplicit(true);
6094 if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
6095 Bases.push_back(BaseTemplD->getTemplatedDecl());
6096 else
6097 Bases.push_back(cast<FunctionDecl>(BaseD));
6098 }
6099
6100 std::string MangledName;
6101 MangledName += D.getIdentifier()->getName();
6102 MangledName += getOpenMPVariantManglingSeparatorStr();
6103 MangledName += DVScope.NameSuffix;
6104 IdentifierInfo &VariantII = Context.Idents.get(MangledName);
6105
6106 VariantII.setMangledOpenMPVariantName(true);
6107 D.SetIdentifier(&VariantII, D.getBeginLoc());
6108}
6109
6110void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
6111 Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) {
6112 // Do not mark function as is used to prevent its emission if this is the
6113 // only place where it is used.
6114 EnterExpressionEvaluationContext Unevaluated(
6115 *this, Sema::ExpressionEvaluationContext::Unevaluated);
6116
6117 FunctionDecl *FD = nullptr;
6118 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6119 FD = UTemplDecl->getTemplatedDecl();
6120 else
6121 FD = cast<FunctionDecl>(D);
6122 auto *VariantFuncRef = DeclRefExpr::Create(
6123 Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
6124 /* RefersToEnclosingVariableOrCapture */ false,
6125 /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue);
6126
6127 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6128 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
6129 Context, VariantFuncRef, DVScope.TI);
6130 for (FunctionDecl *BaseFD : Bases)
6131 BaseFD->addAttr(OMPDeclareVariantA);
6132}
6133
6134ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
6135 SourceLocation LParenLoc,
6136 MultiExprArg ArgExprs,
6137 SourceLocation RParenLoc, Expr *ExecConfig) {
6138 // The common case is a regular call we do not want to specialize at all. Try
6139 // to make that case fast by bailing early.
6140 CallExpr *CE = dyn_cast<CallExpr>(Call.get());
6141 if (!CE)
6142 return Call;
6143
6144 FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
6145 if (!CalleeFnDecl)
6146 return Call;
6147
6148 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
6149 return Call;
6150
6151 ASTContext &Context = getASTContext();
6152 std::function<void(StringRef)> DiagUnknownTrait = [this,
6153 CE](StringRef ISATrait) {
6154 // TODO Track the selector locations in a way that is accessible here to
6155 // improve the diagnostic location.
6156 Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
6157 << ISATrait;
6158 };
6159 TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
6160 getCurFunctionDecl());
6161
6162 QualType CalleeFnType = CalleeFnDecl->getType();
6163
6164 SmallVector<Expr *, 4> Exprs;
6165 SmallVector<VariantMatchInfo, 4> VMIs;
6166 while (CalleeFnDecl) {
6167 for (OMPDeclareVariantAttr *A :
6168 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
6169 Expr *VariantRef = A->getVariantFuncRef();
6170
6171 VariantMatchInfo VMI;
6172 OMPTraitInfo &TI = A->getTraitInfo();
6173 TI.getAsVariantMatchInfo(Context, VMI);
6174 if (!isVariantApplicableInContext(VMI, OMPCtx,
6175 /* DeviceSetOnly */ false))
6176 continue;
6177
6178 VMIs.push_back(VMI);
6179 Exprs.push_back(VariantRef);
6180 }
6181
6182 CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
6183 }
6184
6185 ExprResult NewCall;
6186 do {
6187 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
6188 if (BestIdx < 0)
6189 return Call;
6190 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
6191 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
6192
6193 {
6194 // Try to build a (member) call expression for the current best applicable
6195 // variant expression. We allow this to fail in which case we continue
6196 // with the next best variant expression. The fail case is part of the
6197 // implementation defined behavior in the OpenMP standard when it talks
6198 // about what differences in the function prototypes: "Any differences
6199 // that the specific OpenMP context requires in the prototype of the
6200 // variant from the base function prototype are implementation defined."
6201 // This wording is there to allow the specialized variant to have a
6202 // different type than the base function. This is intended and OK but if
6203 // we cannot create a call the difference is not in the "implementation
6204 // defined range" we allow.
6205 Sema::TentativeAnalysisScope Trap(*this);
6206
6207 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
6208 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
6209 BestExpr = MemberExpr::CreateImplicit(
6210 Context, MemberCall->getImplicitObjectArgument(),
6211 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
6212 MemberCall->getValueKind(), MemberCall->getObjectKind());
6213 }
6214 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
6215 ExecConfig);
6216 if (NewCall.isUsable()) {
6217 if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
6218 FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
6219 QualType NewType = Context.mergeFunctionTypes(
6220 CalleeFnType, NewCalleeFnDecl->getType(),
6221 /* OfBlockPointer */ false,
6222 /* Unqualified */ false, /* AllowCXX */ true);
6223 if (!NewType.isNull())
6224 break;
6225 // Don't use the call if the function type was not compatible.
6226 NewCall = nullptr;
6227 }
6228 }
6229 }
6230
6231 VMIs.erase(VMIs.begin() + BestIdx);
6232 Exprs.erase(Exprs.begin() + BestIdx);
6233 } while (!VMIs.empty());
6234
6235 if (!NewCall.isUsable())
6236 return Call;
6237 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
6238}
6239
6240Optional<std::pair<FunctionDecl *, Expr *>>
6241Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
6242 Expr *VariantRef, OMPTraitInfo &TI,
6243 SourceRange SR) {
6244 if (!DG || DG.get().isNull())
6245 return None;
6246
6247 const int VariantId = 1;
6248 // Must be applied only to single decl.
6249 if (!DG.get().isSingleDecl()) {
6250 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6251 << VariantId << SR;
6252 return None;
6253 }
6254 Decl *ADecl = DG.get().getSingleDecl();
6255 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6256 ADecl = FTD->getTemplatedDecl();
6257
6258 // Decl must be a function.
6259 auto *FD = dyn_cast<FunctionDecl>(ADecl);
6260 if (!FD) {
6261 Diag(ADecl->getLocation(), diag::err_omp_function_expected)
6262 << VariantId << SR;
6263 return None;
6264 }
6265
6266 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
6267 return FD->hasAttrs() &&
6268 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() ||
6269 FD->hasAttr<TargetAttr>());
6270 };
6271 // OpenMP is not compatible with CPU-specific attributes.
6272 if (HasMultiVersionAttributes(FD)) {
6273 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
6274 << SR;
6275 return None;
6276 }
6277
6278 // Allow #pragma omp declare variant only if the function is not used.
6279 if (FD->isUsed(false))
6280 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
6281 << FD->getLocation();
6282
6283 // Check if the function was emitted already.
6284 const FunctionDecl *Definition;
6285 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
6286 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
6287 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
6288 << FD->getLocation();
6289
6290 // The VariantRef must point to function.
6291 if (!VariantRef) {
6292 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
6293 return None;
6294 }
6295
6296 auto ShouldDelayChecks = [](Expr *&E, bool) {
6297 return E && (E->isTypeDependent() || E->isValueDependent() ||
6298 E->containsUnexpandedParameterPack() ||
6299 E->isInstantiationDependent());
6300 };
6301 // Do not check templates, wait until instantiation.
6302 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
6303 TI.anyScoreOrCondition(ShouldDelayChecks))
6304 return std::make_pair(FD, VariantRef);
6305
6306 // Deal with non-constant score and user condition expressions.
6307 auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
6308 bool IsScore) -> bool {
6309 if (!E || E->isIntegerConstantExpr(Context))
6310 return false;
6311
6312 if (IsScore) {
6313 // We warn on non-constant scores and pretend they were not present.
6314 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
6315 << E;
6316 E = nullptr;
6317 } else {
6318 // We could replace a non-constant user condition with "false" but we
6319 // will soon need to handle these anyway for the dynamic version of
6320 // OpenMP context selectors.
6321 Diag(E->getExprLoc(),
6322 diag::err_omp_declare_variant_user_condition_not_constant)
6323 << E;
6324 }
6325 return true;
6326 };
6327 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
6328 return None;
6329
6330 // Convert VariantRef expression to the type of the original function to
6331 // resolve possible conflicts.
6332 ExprResult VariantRefCast = VariantRef;
6333 if (LangOpts.CPlusPlus) {
6334 QualType FnPtrType;
6335 auto *Method = dyn_cast<CXXMethodDecl>(FD);
6336 if (Method && !Method->isStatic()) {
6337 const Type *ClassType =
6338 Context.getTypeDeclType(Method->getParent()).getTypePtr();
6339 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType);
6340 ExprResult ER;
6341 {
6342 // Build adrr_of unary op to correctly handle type checks for member
6343 // functions.
6344 Sema::TentativeAnalysisScope Trap(*this);
6345 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
6346 VariantRef);
6347 }
6348 if (!ER.isUsable()) {
6349 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6350 << VariantId << VariantRef->getSourceRange();
6351 return None;
6352 }
6353 VariantRef = ER.get();
6354 } else {
6355 FnPtrType = Context.getPointerType(FD->getType());
6356 }
6357 QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
6358 if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
6359 ImplicitConversionSequence ICS = TryImplicitConversion(
6360 VariantRef, FnPtrType.getUnqualifiedType(),
6361 /*SuppressUserConversions=*/false, AllowedExplicit::None,
6362 /*InOverloadResolution=*/false,
6363 /*CStyle=*/false,
6364 /*AllowObjCWritebackConversion=*/false);
6365 if (ICS.isFailure()) {
6366 Diag(VariantRef->getExprLoc(),
6367 diag::err_omp_declare_variant_incompat_types)
6368 << VariantRef->getType()
6369 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
6370 << VariantRef->getSourceRange();
6371 return None;
6372 }
6373 VariantRefCast = PerformImplicitConversion(
6374 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
6375 if (!VariantRefCast.isUsable())
6376 return None;
6377 }
6378 // Drop previously built artificial addr_of unary op for member functions.
6379 if (Method && !Method->isStatic()) {
6380 Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
6381 if (auto *UO = dyn_cast<UnaryOperator>(
6382 PossibleAddrOfVariantRef->IgnoreImplicit()))
6383 VariantRefCast = UO->getSubExpr();
6384 }
6385 }
6386
6387 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
6388 if (!ER.isUsable() ||
6389 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
6390 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6391 << VariantId << VariantRef->getSourceRange();
6392 return None;
6393 }
6394
6395 // The VariantRef must point to function.
6396 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
6397 if (!DRE) {
6398 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6399 << VariantId << VariantRef->getSourceRange();
6400 return None;
6401 }
6402 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
6403 if (!NewFD) {
6404 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6405 << VariantId << VariantRef->getSourceRange();
6406 return None;
6407 }
6408
6409 // Check if function types are compatible in C.
6410 if (!LangOpts.CPlusPlus) {
6411 QualType NewType =
6412 Context.mergeFunctionTypes(FD->getType(), NewFD->getType());
6413 if (NewType.isNull()) {
6414 Diag(VariantRef->getExprLoc(),
6415 diag::err_omp_declare_variant_incompat_types)
6416 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange();
6417 return None;
6418 }
6419 if (NewType->isFunctionProtoType()) {
6420 if (FD->getType()->isFunctionNoProtoType())
6421 setPrototype(*this, FD, NewFD, NewType);
6422 else if (NewFD->getType()->isFunctionNoProtoType())
6423 setPrototype(*this, NewFD, FD, NewType);
6424 }
6425 }
6426
6427 // Check if variant function is not marked with declare variant directive.
6428 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
6429 Diag(VariantRef->getExprLoc(),
6430 diag::warn_omp_declare_variant_marked_as_declare_variant)
6431 << VariantRef->getSourceRange();
6432 SourceRange SR =
6433 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
6434 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
6435 return None;
6436 }
6437
6438 enum DoesntSupport {
6439 VirtFuncs = 1,
6440 Constructors = 3,
6441 Destructors = 4,
6442 DeletedFuncs = 5,
6443 DefaultedFuncs = 6,
6444 ConstexprFuncs = 7,
6445 ConstevalFuncs = 8,
6446 };
6447 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
6448 if (CXXFD->isVirtual()) {
6449 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6450 << VirtFuncs;
6451 return None;
6452 }
6453
6454 if (isa<CXXConstructorDecl>(FD)) {
6455 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6456 << Constructors;
6457 return None;
6458 }
6459
6460 if (isa<CXXDestructorDecl>(FD)) {
6461 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6462 << Destructors;
6463 return None;
6464 }
6465 }
6466
6467 if (FD->isDeleted()) {
6468 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6469 << DeletedFuncs;
6470 return None;
6471 }
6472
6473 if (FD->isDefaulted()) {
6474 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6475 << DefaultedFuncs;
6476 return None;
6477 }
6478
6479 if (FD->isConstexpr()) {
6480 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6481 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
6482 return None;
6483 }
6484
6485 // Check general compatibility.
6486 if (areMultiversionVariantFunctionsCompatible(
6487 FD, NewFD, PartialDiagnostic::NullDiagnostic(),
6488 PartialDiagnosticAt(SourceLocation(),
6489 PartialDiagnostic::NullDiagnostic()),
6490 PartialDiagnosticAt(
6491 VariantRef->getExprLoc(),
6492 PDiag(diag::err_omp_declare_variant_doesnt_support)),
6493 PartialDiagnosticAt(VariantRef->getExprLoc(),
6494 PDiag(diag::err_omp_declare_variant_diff)
6495 << FD->getLocation()),
6496 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
6497 /*CLinkageMayDiffer=*/true))
6498 return None;
6499 return std::make_pair(FD, cast<Expr>(DRE));
6500}
6501
6502void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD,
6503 Expr *VariantRef,
6504 OMPTraitInfo &TI,
6505 SourceRange SR) {
6506 auto *NewAttr =
6507 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR);
6508 FD->addAttr(NewAttr);
6509}
6510
6511StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
6512 Stmt *AStmt,
6513 SourceLocation StartLoc,
6514 SourceLocation EndLoc) {
6515 if (!AStmt)
6516 return StmtError();
6517
6518 auto *CS = cast<CapturedStmt>(AStmt);
6519 // 1.2.2 OpenMP Language Terminology
6520 // Structured block - An executable statement with a single entry at the
6521 // top and a single exit at the bottom.
6522 // The point of exit cannot be a branch out of the structured block.
6523 // longjmp() and throw() must not violate the entry/exit criteria.
6524 CS->getCapturedDecl()->setNothrow();
6525
6526 setFunctionHasBranchProtectedScope();
6527
6528 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6529 DSAStack->getTaskgroupReductionRef(),
6530 DSAStack->isCancelRegion());
6531}
6532
6533namespace {
6534/// Iteration space of a single for loop.
6535struct LoopIterationSpace final {
6536 /// True if the condition operator is the strict compare operator (<, > or
6537 /// !=).
6538 bool IsStrictCompare = false;
6539 /// Condition of the loop.
6540 Expr *PreCond = nullptr;
6541 /// This expression calculates the number of iterations in the loop.
6542 /// It is always possible to calculate it before starting the loop.
6543 Expr *NumIterations = nullptr;
6544 /// The loop counter variable.
6545 Expr *CounterVar = nullptr;
6546 /// Private loop counter variable.
6547 Expr *PrivateCounterVar = nullptr;
6548 /// This is initializer for the initial value of #CounterVar.
6549 Expr *CounterInit = nullptr;
6550 /// This is step for the #CounterVar used to generate its update:
6551 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
6552 Expr *CounterStep = nullptr;
6553 /// Should step be subtracted?
6554 bool Subtract = false;
6555 /// Source range of the loop init.
6556 SourceRange InitSrcRange;
6557 /// Source range of the loop condition.
6558 SourceRange CondSrcRange;
6559 /// Source range of the loop increment.
6560 SourceRange IncSrcRange;
6561 /// Minimum value that can have the loop control variable. Used to support
6562 /// non-rectangular loops. Applied only for LCV with the non-iterator types,
6563 /// since only such variables can be used in non-loop invariant expressions.
6564 Expr *MinValue = nullptr;
6565 /// Maximum value that can have the loop control variable. Used to support
6566 /// non-rectangular loops. Applied only for LCV with the non-iterator type,
6567 /// since only such variables can be used in non-loop invariant expressions.
6568 Expr *MaxValue = nullptr;
6569 /// true, if the lower bound depends on the outer loop control var.
6570 bool IsNonRectangularLB = false;
6571 /// true, if the upper bound depends on the outer loop control var.
6572 bool IsNonRectangularUB = false;
6573 /// Index of the loop this loop depends on and forms non-rectangular loop
6574 /// nest.
6575 unsigned LoopDependentIdx = 0;
6576 /// Final condition for the non-rectangular loop nest support. It is used to
6577 /// check that the number of iterations for this particular counter must be
6578 /// finished.
6579 Expr *FinalCondition = nullptr;
6580};
6581
6582/// Helper class for checking canonical form of the OpenMP loops and
6583/// extracting iteration space of each loop in the loop nest, that will be used
6584/// for IR generation.
6585class OpenMPIterationSpaceChecker {
6586 /// Reference to Sema.
6587 Sema &SemaRef;
6588 /// Data-sharing stack.
6589 DSAStackTy &Stack;
6590 /// A location for diagnostics (when there is no some better location).
6591 SourceLocation DefaultLoc;
6592 /// A location for diagnostics (when increment is not compatible).
6593 SourceLocation ConditionLoc;
6594 /// A source location for referring to loop init later.
6595 SourceRange InitSrcRange;
6596 /// A source location for referring to condition later.
6597 SourceRange ConditionSrcRange;
6598 /// A source location for referring to increment later.
6599 SourceRange IncrementSrcRange;
6600 /// Loop variable.
6601 ValueDecl *LCDecl = nullptr;
6602 /// Reference to loop variable.
6603 Expr *LCRef = nullptr;
6604 /// Lower bound (initializer for the var).
6605 Expr *LB = nullptr;
6606 /// Upper bound.
6607 Expr *UB = nullptr;
6608 /// Loop step (increment).
6609 Expr *Step = nullptr;
6610 /// This flag is true when condition is one of:
6611 /// Var < UB
6612 /// Var <= UB
6613 /// UB > Var
6614 /// UB >= Var
6615 /// This will have no value when the condition is !=
6616 llvm::Optional<bool> TestIsLessOp;
6617 /// This flag is true when condition is strict ( < or > ).
6618 bool TestIsStrictOp = false;
6619 /// This flag is true when step is subtracted on each iteration.
6620 bool SubtractStep = false;
6621 /// The outer loop counter this loop depends on (if any).
6622 const ValueDecl *DepDecl = nullptr;
6623 /// Contains number of loop (starts from 1) on which loop counter init
6624 /// expression of this loop depends on.
6625 Optional<unsigned> InitDependOnLC;
6626 /// Contains number of loop (starts from 1) on which loop counter condition
6627 /// expression of this loop depends on.
6628 Optional<unsigned> CondDependOnLC;
6629 /// Checks if the provide statement depends on the loop counter.
6630 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
6631 /// Original condition required for checking of the exit condition for
6632 /// non-rectangular loop.
6633 Expr *Condition = nullptr;
6634
6635public:
6636 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack,
6637 SourceLocation DefaultLoc)
6638 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc),
6639 ConditionLoc(DefaultLoc) {}
6640 /// Check init-expr for canonical loop form and save loop counter
6641 /// variable - #Var and its initialization value - #LB.
6642 bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
6643 /// Check test-expr for canonical form, save upper-bound (#UB), flags
6644 /// for less/greater and for strict/non-strict comparison.
6645 bool checkAndSetCond(Expr *S);
6646 /// Check incr-expr for canonical loop form and return true if it
6647 /// does not conform, otherwise save loop step (#Step).
6648 bool checkAndSetInc(Expr *S);
6649 /// Return the loop counter variable.
6650 ValueDecl *getLoopDecl() const { return LCDecl; }
6651 /// Return the reference expression to loop counter variable.
6652 Expr *getLoopDeclRefExpr() const { return LCRef; }
6653 /// Source range of the loop init.
6654 SourceRange getInitSrcRange() const { return InitSrcRange; }
6655 /// Source range of the loop condition.
6656 SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
6657 /// Source range of the loop increment.
6658 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
6659 /// True if the step should be subtracted.
6660 bool shouldSubtractStep() const { return SubtractStep; }
6661 /// True, if the compare operator is strict (<, > or !=).
6662 bool isStrictTestOp() const { return TestIsStrictOp; }
6663 /// Build the expression to calculate the number of iterations.
6664 Expr *buildNumIterations(
6665 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
6666 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6667 /// Build the precondition expression for the loops.
6668 Expr *
6669 buildPreCond(Scope *S, Expr *Cond,
6670 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6671 /// Build reference expression to the counter be used for codegen.
6672 DeclRefExpr *
6673 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
6674 DSAStackTy &DSA) const;
6675 /// Build reference expression to the private counter be used for
6676 /// codegen.
6677 Expr *buildPrivateCounterVar() const;
6678 /// Build initialization of the counter be used for codegen.
6679 Expr *buildCounterInit() const;
6680 /// Build step of the counter be used for codegen.
6681 Expr *buildCounterStep() const;
6682 /// Build loop data with counter value for depend clauses in ordered
6683 /// directives.
6684 Expr *
6685 buildOrderedLoopData(Scope *S, Expr *Counter,
6686 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
6687 SourceLocation Loc, Expr *Inc = nullptr,
6688 OverloadedOperatorKind OOK = OO_Amp);
6689 /// Builds the minimum value for the loop counter.
6690 std::pair<Expr *, Expr *> buildMinMaxValues(
6691 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6692 /// Builds final condition for the non-rectangular loops.
6693 Expr *buildFinalCondition(Scope *S) const;
6694 /// Return true if any expression is dependent.
6695 bool dependent() const;
6696 /// Returns true if the initializer forms non-rectangular loop.
6697 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); }
6698 /// Returns true if the condition forms non-rectangular loop.
6699 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); }
6700 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
6701 unsigned getLoopDependentIdx() const {
6702 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
6703 }
6704
6705private:
6706 /// Check the right-hand side of an assignment in the increment
6707 /// expression.
6708 bool checkAndSetIncRHS(Expr *RHS);
6709 /// Helper to set loop counter variable and its initializer.
6710 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
6711 bool EmitDiags);
6712 /// Helper to set upper bound.
6713 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
6714 SourceRange SR, SourceLocation SL);
6715 /// Helper to set loop increment.
6716 bool setStep(Expr *NewStep, bool Subtract);
6717};
6718
6719bool OpenMPIterationSpaceChecker::dependent() const {
6720 if (!LCDecl) {
6721 assert(!LB && !UB && !Step);
6722 return false;
6723 }
6724 return LCDecl->getType()->isDependentType() ||
6725 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
6726 (Step && Step->isValueDependent());
6727}
6728
6729bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
6730 Expr *NewLCRefExpr,
6731 Expr *NewLB, bool EmitDiags) {
6732 // State consistency checking to ensure correct usage.
6733 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
6734 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
6735 if (!NewLCDecl || !NewLB)
6736 return true;
6737 LCDecl = getCanonicalDecl(NewLCDecl);
6738 LCRef = NewLCRefExpr;
6739 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
6740 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
6741 if ((Ctor->isCopyOrMoveConstructor() ||
6742 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
6743 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
6744 NewLB = CE->getArg(0)->IgnoreParenImpCasts();
6745 LB = NewLB;
6746 if (EmitDiags)
6747 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
6748 return false;
6749}
6750
6751bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
6752 llvm::Optional<bool> LessOp,
6753 bool StrictOp, SourceRange SR,
6754 SourceLocation SL) {
6755 // State consistency checking to ensure correct usage.
6756 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
6757 Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
6758 if (!NewUB)
6759 return true;
6760 UB = NewUB;
6761 if (LessOp)
6762 TestIsLessOp = LessOp;
6763 TestIsStrictOp = StrictOp;
6764 ConditionSrcRange = SR;
6765 ConditionLoc = SL;
6766 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
6767 return false;
6768}
6769
6770bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
6771 // State consistency checking to ensure correct usage.
6772 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
6773 if (!NewStep)
6774 return true;
6775 if (!NewStep->isValueDependent()) {
6776 // Check that the step is integer expression.
6777 SourceLocation StepLoc = NewStep->getBeginLoc();
6778 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
6779 StepLoc, getExprAsWritten(NewStep));
6780 if (Val.isInvalid())
6781 return true;
6782 NewStep = Val.get();
6783
6784 // OpenMP [2.6, Canonical Loop Form, Restrictions]
6785 // If test-expr is of form var relational-op b and relational-op is < or
6786 // <= then incr-expr must cause var to increase on each iteration of the
6787 // loop. If test-expr is of form var relational-op b and relational-op is
6788 // > or >= then incr-expr must cause var to decrease on each iteration of
6789 // the loop.
6790 // If test-expr is of form b relational-op var and relational-op is < or
6791 // <= then incr-expr must cause var to decrease on each iteration of the
6792 // loop. If test-expr is of form b relational-op var and relational-op is
6793 // > or >= then incr-expr must cause var to increase on each iteration of
6794 // the loop.
6795 Optional<llvm::APSInt> Result =
6796 NewStep->getIntegerConstantExpr(SemaRef.Context);
6797 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
6798 bool IsConstNeg =
6799 Result && Result->isSigned() && (Subtract != Result->isNegative());
6800 bool IsConstPos =
6801 Result && Result->isSigned() && (Subtract == Result->isNegative());
6802 bool IsConstZero = Result && !Result->getBoolValue();
6803
6804 // != with increment is treated as <; != with decrement is treated as >
6805 if (!TestIsLessOp.hasValue())
6806 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
6807 if (UB && (IsConstZero ||
6808 (TestIsLessOp.getValue() ?
6809 (IsConstNeg || (IsUnsigned && Subtract)) :
6810 (IsConstPos || (IsUnsigned && !Subtract))))) {
6811 SemaRef.Diag(NewStep->getExprLoc(),
6812 diag::err_omp_loop_incr_not_compatible)
6813 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
6814 SemaRef.Diag(ConditionLoc,
6815 diag::note_omp_loop_cond_requres_compatible_incr)
6816 << TestIsLessOp.getValue() << ConditionSrcRange;
6817 return true;
6818 }
6819 if (TestIsLessOp.getValue() == Subtract) {
6820 NewStep =
6821 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
6822 .get();
6823 Subtract = !Subtract;
6824 }
6825 }
6826
6827 Step = NewStep;
6828 SubtractStep = Subtract;
6829 return false;
6830}
6831
6832namespace {
6833/// Checker for the non-rectangular loops. Checks if the initializer or
6834/// condition expression references loop counter variable.
6835class LoopCounterRefChecker final
6836 : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
6837 Sema &SemaRef;
6838 DSAStackTy &Stack;
6839 const ValueDecl *CurLCDecl = nullptr;
6840 const ValueDecl *DepDecl = nullptr;
6841 const ValueDecl *PrevDepDecl = nullptr;
6842 bool IsInitializer = true;
6843 unsigned BaseLoopId = 0;
6844 bool checkDecl(const Expr *E, const ValueDecl *VD) {
6845 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
6846 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
6847 << (IsInitializer ? 0 : 1);
6848 return false;
6849 }
6850 const auto &&Data = Stack.isLoopControlVariable(VD);
6851 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
6852 // The type of the loop iterator on which we depend may not have a random
6853 // access iterator type.
6854 if (Data.first && VD->getType()->isRecordType()) {
6855 SmallString<128> Name;
6856 llvm::raw_svector_ostream OS(Name);
6857 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
6858 /*Qualified=*/true);
6859 SemaRef.Diag(E->getExprLoc(),
6860 diag::err_omp_wrong_dependency_iterator_type)
6861 << OS.str();
6862 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
6863 return false;
6864 }
6865 if (Data.first &&
6866 (DepDecl || (PrevDepDecl &&
6867 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
6868 if (!DepDecl && PrevDepDecl)
6869 DepDecl = PrevDepDecl;
6870 SmallString<128> Name;
6871 llvm::raw_svector_ostream OS(Name);
6872 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
6873 /*Qualified=*/true);
6874 SemaRef.Diag(E->getExprLoc(),
6875 diag::err_omp_invariant_or_linear_dependency)
6876 << OS.str();
6877 return false;
6878 }
6879 if (Data.first) {
6880 DepDecl = VD;
6881 BaseLoopId = Data.first;
6882 }
6883 return Data.first;
6884 }
6885
6886public:
6887 bool VisitDeclRefExpr(const DeclRefExpr *E) {
6888 const ValueDecl *VD = E->getDecl();
6889 if (isa<VarDecl>(VD))
6890 return checkDecl(E, VD);
6891 return false;
6892 }
6893 bool VisitMemberExpr(const MemberExpr *E) {
6894 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
6895 const ValueDecl *VD = E->getMemberDecl();
6896 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
6897 return checkDecl(E, VD);
6898 }
6899 return false;
6900 }
6901 bool VisitStmt(const Stmt *S) {
6902 bool Res = false;
6903 for (const Stmt *Child : S->children())
6904 Res = (Child && Visit(Child)) || Res;
6905 return Res;
6906 }
6907 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
6908 const ValueDecl *CurLCDecl, bool IsInitializer,
6909 const ValueDecl *PrevDepDecl = nullptr)
6910 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
6911 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {}
6912 unsigned getBaseLoopId() const {
6913 assert(CurLCDecl && "Expected loop dependency.");
6914 return BaseLoopId;
6915 }
6916 const ValueDecl *getDepDecl() const {
6917 assert(CurLCDecl && "Expected loop dependency.");
6918 return DepDecl;
6919 }
6920};
6921} // namespace
6922
6923Optional<unsigned>
6924OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
6925 bool IsInitializer) {
6926 // Check for the non-rectangular loops.
6927 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
6928 DepDecl);
6929 if (LoopStmtChecker.Visit(S)) {
6930 DepDecl = LoopStmtChecker.getDepDecl();
6931 return LoopStmtChecker.getBaseLoopId();
6932 }
6933 return llvm::None;
6934}
6935
6936bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
6937 // Check init-expr for canonical loop form and save loop counter
6938 // variable - #Var and its initialization value - #LB.
6939 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
6940 // var = lb
6941 // integer-type var = lb
6942 // random-access-iterator-type var = lb
6943 // pointer-type var = lb
6944 //
6945 if (!S) {
6946 if (EmitDiags) {
6947 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
6948 }
6949 return true;
6950 }
6951 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
6952 if (!ExprTemp->cleanupsHaveSideEffects())
6953 S = ExprTemp->getSubExpr();
6954
6955 InitSrcRange = S->getSourceRange();
6956 if (Expr *E = dyn_cast<Expr>(S))
6957 S = E->IgnoreParens();
6958 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
6959 if (BO->getOpcode() == BO_Assign) {
6960 Expr *LHS = BO->getLHS()->IgnoreParens();
6961 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
6962 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
6963 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
6964 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6965 EmitDiags);
6966 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
6967 }
6968 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
6969 if (ME->isArrow() &&
6970 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6971 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6972 EmitDiags);
6973 }
6974 }
6975 } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
6976 if (DS->isSingleDecl()) {
6977 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
6978 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
6979 // Accept non-canonical init form here but emit ext. warning.
6980 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
6981 SemaRef.Diag(S->getBeginLoc(),
6982 diag::ext_omp_loop_not_canonical_init)
6983 << S->getSourceRange();
6984 return setLCDeclAndLB(
6985 Var,
6986 buildDeclRefExpr(SemaRef, Var,
6987 Var->getType().getNonReferenceType(),
6988 DS->getBeginLoc()),
6989 Var->getInit(), EmitDiags);
6990 }
6991 }
6992 }
6993 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6994 if (CE->getOperator() == OO_Equal) {
6995 Expr *LHS = CE->getArg(0);
6996 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
6997 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
6998 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
6999 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7000 EmitDiags);
7001 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
7002 }
7003 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
7004 if (ME->isArrow() &&
7005 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7006 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7007 EmitDiags);
7008 }
7009 }
7010 }
7011
7012 if (dependent() || SemaRef.CurContext->isDependentContext())
7013 return false;
7014 if (EmitDiags) {
7015 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
7016 << S->getSourceRange();
7017 }
7018 return true;
7019}
7020
7021/// Ignore parenthesizes, implicit casts, copy constructor and return the
7022/// variable (which may be the loop variable) if possible.
7023static const ValueDecl *getInitLCDecl(const Expr *E) {
7024 if (!E)
7025 return nullptr;
7026 E = getExprAsWritten(E);
7027 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
7028 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7029 if ((Ctor->isCopyOrMoveConstructor() ||
7030 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7031 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7032 E = CE->getArg(0)->IgnoreParenImpCasts();
7033 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
7034 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
7035 return getCanonicalDecl(VD);
7036 }
7037 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
7038 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7039 return getCanonicalDecl(ME->getMemberDecl());
7040 return nullptr;
7041}
7042
7043bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
7044 // Check test-expr for canonical form, save upper-bound UB, flags for
7045 // less/greater and for strict/non-strict comparison.
7046 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
7047 // var relational-op b
7048 // b relational-op var
7049 //
7050 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
7051 if (!S) {
7052 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
7053 << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
7054 return true;
7055 }
7056 Condition = S;
7057 S = getExprAsWritten(S);
7058 SourceLocation CondLoc = S->getBeginLoc();
7059 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7060 if (BO->isRelationalOp()) {
7061 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7062 return setUB(BO->getRHS(),
7063 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
7064 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
7065 BO->getSourceRange(), BO->getOperatorLoc());
7066 if (getInitLCDecl(BO->getRHS()) == LCDecl)
7067 return setUB(BO->getLHS(),
7068 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
7069 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
7070 BO->getSourceRange(), BO->getOperatorLoc());
7071 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE)
7072 return setUB(
7073 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(),
7074 /*LessOp=*/llvm::None,
7075 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc());
7076 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7077 if (CE->getNumArgs() == 2) {
7078 auto Op = CE->getOperator();
7079 switch (Op) {
7080 case OO_Greater:
7081 case OO_GreaterEqual:
7082 case OO_Less:
7083 case OO_LessEqual:
7084 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7085 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
7086 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
7087 CE->getOperatorLoc());
7088 if (getInitLCDecl(CE->getArg(1)) == LCDecl)
7089 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
7090 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
7091 CE->getOperatorLoc());
7092 break;
7093 case OO_ExclaimEqual:
7094 if (IneqCondIsCanonical)
7095 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1)
7096 : CE->getArg(0),
7097 /*LessOp=*/llvm::None,
7098 /*StrictOp=*/true, CE->getSourceRange(),
7099 CE->getOperatorLoc());
7100 break;
7101 default:
7102 break;
7103 }
7104 }
7105 }
7106 if (dependent() || SemaRef.CurContext->isDependentContext())
7107 return false;
7108 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
7109 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
7110 return true;
7111}
7112
7113bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
7114 // RHS of canonical loop form increment can be:
7115 // var + incr
7116 // incr + var
7117 // var - incr
7118 //
7119 RHS = RHS->IgnoreParenImpCasts();
7120 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
7121 if (BO->isAdditiveOp()) {
7122 bool IsAdd = BO->getOpcode() == BO_Add;
7123 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7124 return setStep(BO->getRHS(), !IsAdd);
7125 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
7126 return setStep(BO->getLHS(), /*Subtract=*/false);
7127 }
7128 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
7129 bool IsAdd = CE->getOperator() == OO_Plus;
7130 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
7131 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7132 return setStep(CE->getArg(1), !IsAdd);
7133 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
7134 return setStep(CE->getArg(0), /*Subtract=*/false);
7135 }
7136 }
7137 if (dependent() || SemaRef.CurContext->isDependentContext())
7138 return false;
7139 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7140 << RHS->getSourceRange() << LCDecl;
7141 return true;
7142}
7143
7144bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
7145 // Check incr-expr for canonical loop form and return true if it
7146 // does not conform.
7147 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
7148 // ++var
7149 // var++
7150 // --var
7151 // var--
7152 // var += incr
7153 // var -= incr
7154 // var = var + incr
7155 // var = incr + var
7156 // var = var - incr
7157 //
7158 if (!S) {
7159 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
7160 return true;
7161 }
7162 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
7163 if (!ExprTemp->cleanupsHaveSideEffects())
7164 S = ExprTemp->getSubExpr();
7165
7166 IncrementSrcRange = S->getSourceRange();
7167 S = S->IgnoreParens();
7168 if (auto *UO = dyn_cast<UnaryOperator>(S)) {
7169 if (UO->isIncrementDecrementOp() &&
7170 getInitLCDecl(UO->getSubExpr()) == LCDecl)
7171 return setStep(SemaRef
7172 .ActOnIntegerConstant(UO->getBeginLoc(),
7173 (UO->isDecrementOp() ? -1 : 1))
7174 .get(),
7175 /*Subtract=*/false);
7176 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7177 switch (BO->getOpcode()) {
7178 case BO_AddAssign:
7179 case BO_SubAssign:
7180 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7181 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
7182 break;
7183 case BO_Assign:
7184 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7185 return checkAndSetIncRHS(BO->getRHS());
7186 break;
7187 default:
7188 break;
7189 }
7190 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7191 switch (CE->getOperator()) {
7192 case OO_PlusPlus:
7193 case OO_MinusMinus:
7194 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7195 return setStep(SemaRef
7196 .ActOnIntegerConstant(
7197 CE->getBeginLoc(),
7198 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
7199 .get(),
7200 /*Subtract=*/false);
7201 break;
7202 case OO_PlusEqual:
7203 case OO_MinusEqual:
7204 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7205 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
7206 break;
7207 case OO_Equal:
7208 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7209 return checkAndSetIncRHS(CE->getArg(1));
7210 break;
7211 default:
7212 break;
7213 }
7214 }
7215 if (dependent() || SemaRef.CurContext->isDependentContext())
7216 return false;
7217 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7218 << S->getSourceRange() << LCDecl;
7219 return true;
7220}
7221
7222static ExprResult
7223tryBuildCapture(Sema &SemaRef, Expr *Capture,
7224 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7225 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
7226 return Capture;
7227 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
7228 return SemaRef.PerformImplicitConversion(
7229 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
7230 /*AllowExplicit=*/true);
7231 auto I = Captures.find(Capture);
7232 if (I != Captures.end())
7233 return buildCapture(SemaRef, Capture, I->second);
7234 DeclRefExpr *Ref = nullptr;
7235 ExprResult Res = buildCapture(SemaRef, Capture, Ref);
7236 Captures[Capture] = Ref;
7237 return Res;
7238}
7239
7240/// Calculate number of iterations, transforming to unsigned, if number of
7241/// iterations may be larger than the original type.
7242static Expr *
7243calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
7244 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
7245 bool TestIsStrictOp, bool RoundToStep,
7246 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7247 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
7248 if (!NewStep.isUsable())
7249 return nullptr;
7250 llvm::APSInt LRes, SRes;
7251 bool IsLowerConst = false, IsStepConst = false;
7252 if (Optional<llvm::APSInt> Res = Lower->getIntegerConstantExpr(SemaRef.Context)) {
7253 LRes = *Res;
7254 IsLowerConst = true;
7255 }
7256 if (Optional<llvm::APSInt> Res = Step->getIntegerConstantExpr(SemaRef.Context)) {
7257 SRes = *Res;
7258 IsStepConst = true;
7259 }
7260 bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
7261 ((!TestIsStrictOp && LRes.isNonNegative()) ||
7262 (TestIsStrictOp && LRes.isStrictlyPositive()));
7263 bool NeedToReorganize = false;
7264 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
7265 if (!NoNeedToConvert && IsLowerConst &&
7266 (TestIsStrictOp || (RoundToStep && IsStepConst))) {
7267 NoNeedToConvert = true;
7268 if (RoundToStep) {
7269 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
7270 ? LRes.getBitWidth()
7271 : SRes.getBitWidth();
7272 LRes = LRes.extend(BW + 1);
7273 LRes.setIsSigned(true);
7274 SRes = SRes.extend(BW + 1);
7275 SRes.setIsSigned(true);
7276 LRes -= SRes;
7277 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
7278 LRes = LRes.trunc(BW);
7279 }
7280 if (TestIsStrictOp) {
7281 unsigned BW = LRes.getBitWidth();
7282 LRes = LRes.extend(BW + 1);
7283 LRes.setIsSigned(true);
7284 ++LRes;
7285 NoNeedToConvert =
7286 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
7287 // truncate to the original bitwidth.
7288 LRes = LRes.trunc(BW);
7289 }
7290 NeedToReorganize = NoNeedToConvert;
7291 }
7292 llvm::APSInt URes;
7293 bool IsUpperConst = false;
7294 if (Optional<llvm::APSInt> Res = Upper->getIntegerConstantExpr(SemaRef.Context)) {
7295 URes = *Res;
7296 IsUpperConst = true;
7297 }
7298 if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
7299 (!RoundToStep || IsStepConst)) {
7300 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
7301 : URes.getBitWidth();
7302 LRes = LRes.extend(BW + 1);
7303 LRes.setIsSigned(true);
7304 URes = URes.extend(BW + 1);
7305 URes.setIsSigned(true);
7306 URes -= LRes;
7307 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
7308 NeedToReorganize = NoNeedToConvert;
7309 }
7310 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
7311 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
7312 // unsigned.
7313 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
7314 !LCTy->isDependentType() && LCTy->isIntegerType()) {
7315 QualType LowerTy = Lower->getType();
7316 QualType UpperTy = Upper->getType();
7317 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
7318 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
7319 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
7320 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
7321 QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
7322 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
7323 Upper =
7324 SemaRef
7325 .PerformImplicitConversion(
7326 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7327 CastType, Sema::AA_Converting)
7328 .get();
7329 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
7330 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
7331 }
7332 }
7333 if (!Lower || !Upper || NewStep.isInvalid())
7334 return nullptr;
7335
7336 ExprResult Diff;
7337 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
7338 // 1]).
7339 if (NeedToReorganize) {
7340 Diff = Lower;
7341
7342 if (RoundToStep) {
7343 // Lower - Step
7344 Diff =
7345 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
7346 if (!Diff.isUsable())
7347 return nullptr;
7348 }
7349
7350 // Lower - Step [+ 1]
7351 if (TestIsStrictOp)
7352 Diff = SemaRef.BuildBinOp(
7353 S, DefaultLoc, BO_Add, Diff.get(),
7354 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7355 if (!Diff.isUsable())
7356 return nullptr;
7357
7358 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7359 if (!Diff.isUsable())
7360 return nullptr;
7361
7362 // Upper - (Lower - Step [+ 1]).
7363 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
7364 if (!Diff.isUsable())
7365 return nullptr;
7366 } else {
7367 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
7368
7369 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
7370 // BuildBinOp already emitted error, this one is to point user to upper
7371 // and lower bound, and to tell what is passed to 'operator-'.
7372 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
7373 << Upper->getSourceRange() << Lower->getSourceRange();
7374 return nullptr;
7375 }
7376
7377 if (!Diff.isUsable())
7378 return nullptr;
7379
7380 // Upper - Lower [- 1]
7381 if (TestIsStrictOp)
7382 Diff = SemaRef.BuildBinOp(
7383 S, DefaultLoc, BO_Sub, Diff.get(),
7384 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7385 if (!Diff.isUsable())
7386 return nullptr;
7387
7388 if (RoundToStep) {
7389 // Upper - Lower [- 1] + Step
7390 Diff =
7391 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
7392 if (!Diff.isUsable())
7393 return nullptr;
7394 }
7395 }
7396
7397 // Parentheses (for dumping/debugging purposes only).
7398 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7399 if (!Diff.isUsable())
7400 return nullptr;
7401
7402 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
7403 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
7404 if (!Diff.isUsable())
7405 return nullptr;
7406
7407 return Diff.get();
7408}
7409
7410/// Build the expression to calculate the number of iterations.
7411Expr *OpenMPIterationSpaceChecker::buildNumIterations(
7412 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7413 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7414 QualType VarType = LCDecl->getType().getNonReferenceType();
7415 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
7416 !SemaRef.getLangOpts().CPlusPlus)
7417 return nullptr;
7418 Expr *LBVal = LB;
7419 Expr *UBVal = UB;
7420 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
7421 // max(LB(MinVal), LB(MaxVal))
7422 if (InitDependOnLC) {
7423 const LoopIterationSpace &IS =
7424 ResultIterSpaces[ResultIterSpaces.size() - 1 -
7425 InitDependOnLC.getValueOr(
7426 CondDependOnLC.getValueOr(0))];
7427 if (!IS.MinValue || !IS.MaxValue)
7428 return nullptr;
7429 // OuterVar = Min
7430 ExprResult MinValue =
7431 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
7432 if (!MinValue.isUsable())
7433 return nullptr;
7434
7435 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7436 IS.CounterVar, MinValue.get());
7437 if (!LBMinVal.isUsable())
7438 return nullptr;
7439 // OuterVar = Min, LBVal
7440 LBMinVal =
7441 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
7442 if (!LBMinVal.isUsable())
7443 return nullptr;
7444 // (OuterVar = Min, LBVal)
7445 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
7446 if (!LBMinVal.isUsable())
7447 return nullptr;
7448
7449 // OuterVar = Max
7450 ExprResult MaxValue =
7451 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
7452 if (!MaxValue.isUsable())
7453 return nullptr;
7454
7455 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7456 IS.CounterVar, MaxValue.get());
7457 if (!LBMaxVal.isUsable())
7458 return nullptr;
7459 // OuterVar = Max, LBVal
7460 LBMaxVal =
7461 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
7462 if (!LBMaxVal.isUsable())
7463 return nullptr;
7464 // (OuterVar = Max, LBVal)
7465 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
7466 if (!LBMaxVal.isUsable())
7467 return nullptr;
7468
7469 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
7470 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
7471 if (!LBMin || !LBMax)
7472 return nullptr;
7473 // LB(MinVal) < LB(MaxVal)
7474 ExprResult MinLessMaxRes =
7475 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
7476 if (!MinLessMaxRes.isUsable())
7477 return nullptr;
7478 Expr *MinLessMax =
7479 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
7480 if (!MinLessMax)
7481 return nullptr;
7482 if (TestIsLessOp.getValue()) {
7483 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
7484 // LB(MaxVal))
7485 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
7486 MinLessMax, LBMin, LBMax);
7487 if (!MinLB.isUsable())
7488 return nullptr;
7489 LBVal = MinLB.get();
7490 } else {
7491 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
7492 // LB(MaxVal))
7493 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
7494 MinLessMax, LBMax, LBMin);
7495 if (!MaxLB.isUsable())
7496 return nullptr;
7497 LBVal = MaxLB.get();
7498 }
7499 }
7500 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
7501 // min(UB(MinVal), UB(MaxVal))
7502 if (CondDependOnLC) {
7503 const LoopIterationSpace &IS =
7504 ResultIterSpaces[ResultIterSpaces.size() - 1 -
7505 InitDependOnLC.getValueOr(
7506 CondDependOnLC.getValueOr(0))];
7507 if (!IS.MinValue || !IS.MaxValue)
7508 return nullptr;
7509 // OuterVar = Min
7510 ExprResult MinValue =
7511 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
7512 if (!MinValue.isUsable())
7513 return nullptr;
7514
7515 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7516 IS.CounterVar, MinValue.get());
7517 if (!UBMinVal.isUsable())
7518 return nullptr;
7519 // OuterVar = Min, UBVal
7520 UBMinVal =
7521 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
7522 if (!UBMinVal.isUsable())
7523 return nullptr;
7524 // (OuterVar = Min, UBVal)
7525 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
7526 if (!UBMinVal.isUsable())
7527 return nullptr;
7528
7529 // OuterVar = Max
7530 ExprResult MaxValue =
7531 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
7532 if (!MaxValue.isUsable())
7533 return nullptr;
7534
7535 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7536 IS.CounterVar, MaxValue.get());
7537 if (!UBMaxVal.isUsable())
7538 return nullptr;
7539 // OuterVar = Max, UBVal
7540 UBMaxVal =
7541 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
7542 if (!UBMaxVal.isUsable())
7543 return nullptr;
7544 // (OuterVar = Max, UBVal)
7545 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
7546 if (!UBMaxVal.isUsable())
7547 return nullptr;
7548
7549 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
7550 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
7551 if (!UBMin || !UBMax)
7552 return nullptr;
7553 // UB(MinVal) > UB(MaxVal)
7554 ExprResult MinGreaterMaxRes =
7555 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
7556 if (!MinGreaterMaxRes.isUsable())
7557 return nullptr;
7558 Expr *MinGreaterMax =
7559 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
7560 if (!MinGreaterMax)
7561 return nullptr;
7562 if (TestIsLessOp.getValue()) {
7563 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
7564 // UB(MaxVal))
7565 ExprResult MaxUB = SemaRef.ActOnConditionalOp(
7566 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
7567 if (!MaxUB.isUsable())
7568 return nullptr;
7569 UBVal = MaxUB.get();
7570 } else {
7571 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
7572 // UB(MaxVal))
7573 ExprResult MinUB = SemaRef.ActOnConditionalOp(
7574 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
7575 if (!MinUB.isUsable())
7576 return nullptr;
7577 UBVal = MinUB.get();
7578 }
7579 }
7580 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
7581 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
7582 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
7583 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
7584 if (!Upper || !Lower)
7585 return nullptr;
7586
7587 ExprResult Diff =
7588 calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
7589 TestIsStrictOp, /*RoundToStep=*/true, Captures);
7590 if (!Diff.isUsable())
7591 return nullptr;
7592
7593 // OpenMP runtime requires 32-bit or 64-bit loop variables.
7594 QualType Type = Diff.get()->getType();
7595 ASTContext &C = SemaRef.Context;
7596 bool UseVarType = VarType->hasIntegerRepresentation() &&
7597 C.getTypeSize(Type) > C.getTypeSize(VarType);
7598 if (!Type->isIntegerType() || UseVarType) {
7599 unsigned NewSize =
7600 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
7601 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
7602 : Type->hasSignedIntegerRepresentation();
7603 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
7604 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
7605 Diff = SemaRef.PerformImplicitConversion(
7606 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
7607 if (!Diff.isUsable())
7608 return nullptr;
7609 }
7610 }
7611 if (LimitedType) {
7612 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
7613 if (NewSize != C.getTypeSize(Type)) {
7614 if (NewSize < C.getTypeSize(Type)) {
7615 assert(NewSize == 64 && "incorrect loop var size");
7616 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
7617 << InitSrcRange << ConditionSrcRange;
7618 }
7619 QualType NewType = C.getIntTypeForBitwidth(
7620 NewSize, Type->hasSignedIntegerRepresentation() ||
7621 C.getTypeSize(Type) < NewSize);
7622 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
7623 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
7624 Sema::AA_Converting, true);
7625 if (!Diff.isUsable())
7626 return nullptr;
7627 }
7628 }
7629 }
7630
7631 return Diff.get();
7632}
7633
7634std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
7635 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7636 // Do not build for iterators, they cannot be used in non-rectangular loop
7637 // nests.
7638 if (LCDecl->getType()->isRecordType())
7639 return std::make_pair(nullptr, nullptr);
7640 // If we subtract, the min is in the condition, otherwise the min is in the
7641 // init value.
7642 Expr *MinExpr = nullptr;
7643 Expr *MaxExpr = nullptr;
7644 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
7645 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
7646 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
7647 : CondDependOnLC.hasValue();
7648 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
7649 : InitDependOnLC.hasValue();
7650 Expr *Lower =
7651 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
7652 Expr *Upper =
7653 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
7654 if (!Upper || !Lower)
7655 return std::make_pair(nullptr, nullptr);
7656
7657 if (TestIsLessOp.getValue())
7658 MinExpr = Lower;
7659 else
7660 MaxExpr = Upper;
7661
7662 // Build minimum/maximum value based on number of iterations.
7663 QualType VarType = LCDecl->getType().getNonReferenceType();
7664
7665 ExprResult Diff =
7666 calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
7667 TestIsStrictOp, /*RoundToStep=*/false, Captures);
7668 if (!Diff.isUsable())
7669 return std::make_pair(nullptr, nullptr);
7670
7671 // ((Upper - Lower [- 1]) / Step) * Step
7672 // Parentheses (for dumping/debugging purposes only).
7673 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7674 if (!Diff.isUsable())
7675 return std::make_pair(nullptr, nullptr);
7676
7677 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
7678 if (!NewStep.isUsable())
7679 return std::make_pair(nullptr, nullptr);
7680 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
7681 if (!Diff.isUsable())
7682 return std::make_pair(nullptr, nullptr);
7683
7684 // Parentheses (for dumping/debugging purposes only).
7685 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7686 if (!Diff.isUsable())
7687 return std::make_pair(nullptr, nullptr);
7688
7689 // Convert to the ptrdiff_t, if original type is pointer.
7690 if (VarType->isAnyPointerType() &&
7691 !SemaRef.Context.hasSameType(
7692 Diff.get()->getType(),
7693 SemaRef.Context.getUnsignedPointerDiffType())) {
7694 Diff = SemaRef.PerformImplicitConversion(
7695 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
7696 Sema::AA_Converting, /*AllowExplicit=*/true);
7697 }
7698 if (!Diff.isUsable())
7699 return std::make_pair(nullptr, nullptr);
7700
7701 if (TestIsLessOp.getValue()) {
7702 // MinExpr = Lower;
7703 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
7704 Diff = SemaRef.BuildBinOp(
7705 S, DefaultLoc, BO_Add,
7706 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
7707 Diff.get());
7708 if (!Diff.isUsable())
7709 return std::make_pair(nullptr, nullptr);
7710 } else {
7711 // MaxExpr = Upper;
7712 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
7713 Diff = SemaRef.BuildBinOp(
7714 S, DefaultLoc, BO_Sub,
7715 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7716 Diff.get());
7717 if (!Diff.isUsable())
7718 return std::make_pair(nullptr, nullptr);
7719 }
7720
7721 // Convert to the original type.
7722 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
7723 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
7724 Sema::AA_Converting,
7725 /*AllowExplicit=*/true);
7726 if (!Diff.isUsable())
7727 return std::make_pair(nullptr, nullptr);
7728
7729 Sema::TentativeAnalysisScope Trap(SemaRef);
7730 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
7731 if (!Diff.isUsable())
7732 return std::make_pair(nullptr, nullptr);
7733
7734 if (TestIsLessOp.getValue())
7735 MaxExpr = Diff.get();
7736 else
7737 MinExpr = Diff.get();
7738
7739 return std::make_pair(MinExpr, MaxExpr);
7740}
7741
7742Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
7743 if (InitDependOnLC || CondDependOnLC)
7744 return Condition;
7745 return nullptr;
7746}
7747
7748Expr *OpenMPIterationSpaceChecker::buildPreCond(
7749 Scope *S, Expr *Cond,
7750 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7751 // Do not build a precondition when the condition/initialization is dependent
7752 // to prevent pessimistic early loop exit.
7753 // TODO: this can be improved by calculating min/max values but not sure that
7754 // it will be very effective.
7755 if (CondDependOnLC || InitDependOnLC)
7756 return SemaRef.PerformImplicitConversion(
7757 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
7758 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
7759 /*AllowExplicit=*/true).get();
7760
7761 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
7762 Sema::TentativeAnalysisScope Trap(SemaRef);
7763
7764 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
7765 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
7766 if (!NewLB.isUsable() || !NewUB.isUsable())
7767 return nullptr;
7768
7769 ExprResult CondExpr =
7770 SemaRef.BuildBinOp(S, DefaultLoc,
7771 TestIsLessOp.getValue() ?
7772 (TestIsStrictOp ? BO_LT : BO_LE) :
7773 (TestIsStrictOp ? BO_GT : BO_GE),
7774 NewLB.get(), NewUB.get());
7775 if (CondExpr.isUsable()) {
7776 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
7777 SemaRef.Context.BoolTy))
7778 CondExpr = SemaRef.PerformImplicitConversion(
7779 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
7780 /*AllowExplicit=*/true);
7781 }
7782
7783 // Otherwise use original loop condition and evaluate it in runtime.
7784 return CondExpr.isUsable() ? CondExpr.get() : Cond;
7785}
7786
7787/// Build reference expression to the counter be used for codegen.
7788DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
7789 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7790 DSAStackTy &DSA) const {
7791 auto *VD = dyn_cast<VarDecl>(LCDecl);
7792 if (!VD) {
7793 VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
7794 DeclRefExpr *Ref = buildDeclRefExpr(
7795 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
7796 const DSAStackTy::DSAVarData Data =
7797 DSA.getTopDSA(LCDecl, /*FromParent=*/false);
7798 // If the loop control decl is explicitly marked as private, do not mark it
7799 // as captured again.
7800 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
7801 Captures.insert(std::make_pair(LCRef, Ref));
7802 return Ref;
7803 }
7804 return cast<DeclRefExpr>(LCRef);
7805}
7806
7807Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
7808 if (LCDecl && !LCDecl->isInvalidDecl()) {
7809 QualType Type = LCDecl->getType().getNonReferenceType();
7810 VarDecl *PrivateVar = buildVarDecl(
7811 SemaRef, DefaultLoc, Type, LCDecl->getName(),
7812 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
7813 isa<VarDecl>(LCDecl)
7814 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
7815 : nullptr);
7816 if (PrivateVar->isInvalidDecl())
7817 return nullptr;
7818 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
7819 }
7820 return nullptr;
7821}
7822
7823/// Build initialization of the counter to be used for codegen.
7824Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
7825
7826/// Build step of the counter be used for codegen.
7827Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
7828
7829Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
7830 Scope *S, Expr *Counter,
7831 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
7832 Expr *Inc, OverloadedOperatorKind OOK) {
7833 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
7834 if (!Cnt)
7835 return nullptr;
7836 if (Inc) {
7837 assert((OOK == OO_Plus || OOK == OO_Minus) &&
7838 "Expected only + or - operations for depend clauses.");
7839 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
7840 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
7841 if (!Cnt)
7842 return nullptr;
7843 }
7844 QualType VarType = LCDecl->getType().getNonReferenceType();
7845 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
7846 !SemaRef.getLangOpts().CPlusPlus)
7847 return nullptr;
7848 // Upper - Lower
7849 Expr *Upper = TestIsLessOp.getValue()
7850 ? Cnt
7851 : tryBuildCapture(SemaRef, LB, Captures).get();
7852 Expr *Lower = TestIsLessOp.getValue()
7853 ? tryBuildCapture(SemaRef, LB, Captures).get()
7854 : Cnt;
7855 if (!Upper || !Lower)
7856 return nullptr;
7857
7858 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
7859 Step, VarType, /*TestIsStrictOp=*/false,
7860 /*RoundToStep=*/false, Captures);
7861 if (!Diff.isUsable())
7862 return nullptr;
7863
7864 return Diff.get();
7865}
7866} // namespace
7867
7868void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
7869 assert(getLangOpts().OpenMP && "OpenMP is not active.");
7870 assert(Init && "Expected loop in canonical form.");
7871 unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
7872 if (AssociatedLoops > 0 &&
7873 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
7874 DSAStack->loopStart();
7875 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc);
7876 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
7877 if (ValueDecl *D = ISC.getLoopDecl()) {
7878 auto *VD = dyn_cast<VarDecl>(D);
7879 DeclRefExpr *PrivateRef = nullptr;
7880 if (!VD) {
7881 if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
7882 VD = Private;
7883 } else {
7884 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
7885 /*WithInit=*/false);
7886 VD = cast<VarDecl>(PrivateRef->getDecl());
7887 }
7888 }
7889 DSAStack->addLoopControlVariable(D, VD);
7890 const Decl *LD = DSAStack->getPossiblyLoopCunter();
7891 if (LD != D->getCanonicalDecl()) {
7892 DSAStack->resetPossibleLoopCounter();
7893 if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
7894 MarkDeclarationsReferencedInExpr(
7895 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
7896 Var->getType().getNonLValueExprType(Context),
7897 ForLoc, /*RefersToCapture=*/true));
7898 }
7899 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
7900 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
7901 // Referenced in a Construct, C/C++]. The loop iteration variable in the
7902 // associated for-loop of a simd construct with just one associated
7903 // for-loop may be listed in a linear clause with a constant-linear-step
7904 // that is the increment of the associated for-loop. The loop iteration
7905 // variable(s) in the associated for-loop(s) of a for or parallel for
7906 // construct may be listed in a private or lastprivate clause.
7907 DSAStackTy::DSAVarData DVar =
7908 DSAStack->getTopDSA(D, /*FromParent=*/false);
7909 // If LoopVarRefExpr is nullptr it means the corresponding loop variable
7910 // is declared in the loop and it is predetermined as a private.
7911 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
7912 OpenMPClauseKind PredeterminedCKind =
7913 isOpenMPSimdDirective(DKind)
7914 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
7915 : OMPC_private;
7916 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
7917 DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
7918 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
7919 DVar.CKind != OMPC_private))) ||
7920 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
7921 DKind == OMPD_master_taskloop ||
7922 DKind == OMPD_parallel_master_taskloop ||
7923 isOpenMPDistributeDirective(DKind)) &&
7924 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
7925 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
7926 (DVar.CKind != OMPC_private || DVar.RefExpr)) {
7927 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
7928 << getOpenMPClauseName(DVar.CKind)
7929 << getOpenMPDirectiveName(DKind)
7930 << getOpenMPClauseName(PredeterminedCKind);
7931 if (DVar.RefExpr == nullptr)
7932 DVar.CKind = PredeterminedCKind;
7933 reportOriginalDsa(*this, DSAStack, D, DVar,
7934 /*IsLoopIterVar=*/true);
7935 } else if (LoopDeclRefExpr) {
7936 // Make the loop iteration variable private (for worksharing
7937 // constructs), linear (for simd directives with the only one
7938 // associated loop) or lastprivate (for simd directives with several
7939 // collapsed or ordered loops).
7940 if (DVar.CKind == OMPC_unknown)
7941 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
7942 PrivateRef);
7943 }
7944 }
7945 }
7946 DSAStack->setAssociatedLoops(AssociatedLoops - 1);
7947 }
7948}
7949
7950/// Called on a for stmt to check and extract its iteration space
7951/// for further processing (such as collapsing).
7952static bool checkOpenMPIterationSpace(
7953 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
7954 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
7955 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
7956 Expr *OrderedLoopCountExpr,
7957 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
7958 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
7959 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7960 // OpenMP [2.9.1, Canonical Loop Form]
7961 // for (init-expr; test-expr; incr-expr) structured-block
7962 // for (range-decl: range-expr) structured-block
7963 auto *For = dyn_cast_or_null<ForStmt>(S);
7964 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
7965 // Ranged for is supported only in OpenMP 5.0.
7966 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
7967 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
7968 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
7969 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
7970 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
7971 if (TotalNestedLoopCount > 1) {
7972 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
7973 SemaRef.Diag(DSA.getConstructLoc(),
7974 diag::note_omp_collapse_ordered_expr)
7975 << 2 << CollapseLoopCountExpr->getSourceRange()
7976 << OrderedLoopCountExpr->getSourceRange();
7977 else if (CollapseLoopCountExpr)
7978 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
7979 diag::note_omp_collapse_ordered_expr)
7980 << 0 << CollapseLoopCountExpr->getSourceRange();
7981 else
7982 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
7983 diag::note_omp_collapse_ordered_expr)
7984 << 1 << OrderedLoopCountExpr->getSourceRange();
7985 }
7986 return true;
7987 }
7988 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
7989 "No loop body.");
7990
7991 OpenMPIterationSpaceChecker ISC(SemaRef, DSA,
7992 For ? For->getForLoc() : CXXFor->getForLoc());
7993
7994 // Check init.
7995 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
7996 if (ISC.checkAndSetInit(Init))
7997 return true;
7998
7999 bool HasErrors = false;
8000
8001 // Check loop variable's type.
8002 if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
8003 // OpenMP [2.6, Canonical Loop Form]
8004 // Var is one of the following:
8005 // A variable of signed or unsigned integer type.
8006 // For C++, a variable of a random access iterator type.
8007 // For C, a variable of a pointer type.
8008 QualType VarType = LCDecl->getType().getNonReferenceType();
8009 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
8010 !VarType->isPointerType() &&
8011 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
8012 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
8013 << SemaRef.getLangOpts().CPlusPlus;
8014 HasErrors = true;
8015 }
8016
8017 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
8018 // a Construct
8019 // The loop iteration variable(s) in the associated for-loop(s) of a for or
8020 // parallel for construct is (are) private.
8021 // The loop iteration variable in the associated for-loop of a simd
8022 // construct with just one associated for-loop is linear with a
8023 // constant-linear-step that is the increment of the associated for-loop.
8024 // Exclude loop var from the list of variables with implicitly defined data
8025 // sharing attributes.
8026 VarsWithImplicitDSA.erase(LCDecl);
8027
8028 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
8029
8030 // Check test-expr.
8031 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
8032
8033 // Check incr-expr.
8034 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
8035 }
8036
8037 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
8038 return HasErrors;
8039
8040 // Build the loop's iteration space representation.
8041 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
8042 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
8043 ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
8044 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
8045 (isOpenMPWorksharingDirective(DKind) ||
8046 isOpenMPTaskLoopDirective(DKind) ||
8047 isOpenMPDistributeDirective(DKind)),
8048 Captures);
8049 ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
8050 ISC.buildCounterVar(Captures, DSA);
8051 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
8052 ISC.buildPrivateCounterVar();
8053 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
8054 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
8055 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
8056 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
8057 ISC.getConditionSrcRange();
8058 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
8059 ISC.getIncrementSrcRange();
8060 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
8061 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
8062 ISC.isStrictTestOp();
8063 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
8064 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
8065 ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
8066 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
8067 ISC.buildFinalCondition(DSA.getCurScope());
8068 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
8069 ISC.doesInitDependOnLC();
8070 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
8071 ISC.doesCondDependOnLC();
8072 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
8073 ISC.getLoopDependentIdx();
8074
8075 HasErrors |=
8076 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
8077 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
8078 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
8079 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
8080 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
8081 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
8082 if (!HasErrors && DSA.isOrderedRegion()) {
8083 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
8084 if (CurrentNestedLoopCount <
8085 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
8086 DSA.getOrderedRegionParam().second->setLoopNumIterations(
8087 CurrentNestedLoopCount,
8088 ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
8089 DSA.getOrderedRegionParam().second->setLoopCounter(
8090 CurrentNestedLoopCount,
8091 ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
8092 }
8093 }
8094 for (auto &Pair : DSA.getDoacrossDependClauses()) {
8095 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
8096 // Erroneous case - clause has some problems.
8097 continue;
8098 }
8099 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
8100 Pair.second.size() <= CurrentNestedLoopCount) {
8101 // Erroneous case - clause has some problems.
8102 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
8103 continue;
8104 }
8105 Expr *CntValue;
8106 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
8107 CntValue = ISC.buildOrderedLoopData(
8108 DSA.getCurScope(),
8109 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
8110 Pair.first->getDependencyLoc());
8111 else
8112 CntValue = ISC.buildOrderedLoopData(
8113 DSA.getCurScope(),
8114 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
8115 Pair.first->getDependencyLoc(),
8116 Pair.second[CurrentNestedLoopCount].first,
8117 Pair.second[CurrentNestedLoopCount].second);
8118 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
8119 }
8120 }
8121
8122 return HasErrors;
8123}
8124
8125/// Build 'VarRef = Start.
8126static ExprResult
8127buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
8128 ExprResult Start, bool IsNonRectangularLB,
8129 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8130 // Build 'VarRef = Start.
8131 ExprResult NewStart = IsNonRectangularLB
8132 ? Start.get()
8133 : tryBuildCapture(SemaRef, Start.get(), Captures);
8134 if (!NewStart.isUsable())
8135 return ExprError();
8136 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
8137 VarRef.get()->getType())) {
8138 NewStart = SemaRef.PerformImplicitConversion(
8139 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
8140 /*AllowExplicit=*/true);
8141 if (!NewStart.isUsable())
8142 return ExprError();
8143 }
8144
8145 ExprResult Init =
8146 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8147 return Init;
8148}
8149
8150/// Build 'VarRef = Start + Iter * Step'.
8151static ExprResult buildCounterUpdate(
8152 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
8153 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
8154 bool IsNonRectangularLB,
8155 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
8156 // Add parentheses (for debugging purposes only).
8157 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
8158 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
8159 !Step.isUsable())
8160 return ExprError();
8161
8162 ExprResult NewStep = Step;
8163 if (Captures)
8164 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
8165 if (NewStep.isInvalid())
8166 return ExprError();
8167 ExprResult Update =
8168 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
8169 if (!Update.isUsable())
8170 return ExprError();
8171
8172 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
8173 // 'VarRef = Start (+|-) Iter * Step'.
8174 if (!Start.isUsable())
8175 return ExprError();
8176 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
8177 if (!NewStart.isUsable())
8178 return ExprError();
8179 if (Captures && !IsNonRectangularLB)
8180 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
8181 if (NewStart.isInvalid())
8182 return ExprError();
8183
8184 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
8185 ExprResult SavedUpdate = Update;
8186 ExprResult UpdateVal;
8187 if (VarRef.get()->getType()->isOverloadableType() ||
8188 NewStart.get()->getType()->isOverloadableType() ||
8189 Update.get()->getType()->isOverloadableType()) {
8190 Sema::TentativeAnalysisScope Trap(SemaRef);
8191
8192 Update =
8193 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8194 if (Update.isUsable()) {
8195 UpdateVal =
8196 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
8197 VarRef.get(), SavedUpdate.get());
8198 if (UpdateVal.isUsable()) {
8199 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
8200 UpdateVal.get());
8201 }
8202 }
8203 }
8204
8205 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
8206 if (!Update.isUsable() || !UpdateVal.isUsable()) {
8207 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
8208 NewStart.get(), SavedUpdate.get());
8209 if (!Update.isUsable())
8210 return ExprError();
8211
8212 if (!SemaRef.Context.hasSameType(Update.get()->getType(),
8213 VarRef.get()->getType())) {
8214 Update = SemaRef.PerformImplicitConversion(
8215 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
8216 if (!Update.isUsable())
8217 return ExprError();
8218 }
8219
8220 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
8221 }
8222 return Update;
8223}
8224
8225/// Convert integer expression \a E to make it have at least \a Bits
8226/// bits.
8227static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
8228 if (E == nullptr)
8229 return ExprError();
8230 ASTContext &C = SemaRef.Context;
8231 QualType OldType = E->getType();
8232 unsigned HasBits = C.getTypeSize(OldType);
8233 if (HasBits >= Bits)
8234 return ExprResult(E);
8235 // OK to convert to signed, because new type has more bits than old.
8236 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
8237 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
8238 true);
8239}
8240
8241/// Check if the given expression \a E is a constant integer that fits
8242/// into \a Bits bits.
8243static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
8244 if (E == nullptr)
8245 return false;
8246 if (Optional<llvm::APSInt> Result =
8247 E->getIntegerConstantExpr(SemaRef.Context))
8248 return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
8249 return false;
8250}
8251
8252/// Build preinits statement for the given declarations.
8253static Stmt *buildPreInits(ASTContext &Context,
8254 MutableArrayRef<Decl *> PreInits) {
8255 if (!PreInits.empty()) {
8256 return new (Context) DeclStmt(
8257 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
8258 SourceLocation(), SourceLocation());
8259 }
8260 return nullptr;
8261}
8262
8263/// Build preinits statement for the given declarations.
8264static Stmt *
8265buildPreInits(ASTContext &Context,
8266 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8267 if (!Captures.empty()) {
8268 SmallVector<Decl *, 16> PreInits;
8269 for (const auto &Pair : Captures)
8270 PreInits.push_back(Pair.second->getDecl());
8271 return buildPreInits(Context, PreInits);
8272 }
8273 return nullptr;
8274}
8275
8276/// Build postupdate expression for the given list of postupdates expressions.
8277static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
8278 Expr *PostUpdate = nullptr;
8279 if (!PostUpdates.empty()) {
8280 for (Expr *E : PostUpdates) {
8281 Expr *ConvE = S.BuildCStyleCastExpr(
8282 E->getExprLoc(),
8283 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
8284 E->getExprLoc(), E)
8285 .get();
8286 PostUpdate = PostUpdate
8287 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
8288 PostUpdate, ConvE)
8289 .get()
8290 : ConvE;
8291 }
8292 }
8293 return PostUpdate;
8294}
8295
8296/// Called on a for stmt to check itself and nested loops (if any).
8297/// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
8298/// number of collapsed loops otherwise.
8299static unsigned
8300checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
8301 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
8302 DSAStackTy &DSA,
8303 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8304 OMPLoopDirective::HelperExprs &Built) {
8305 unsigned NestedLoopCount = 1;
8306 if (CollapseLoopCountExpr) {
8307 // Found 'collapse' clause - calculate collapse number.
8308 Expr::EvalResult Result;
8309 if (!CollapseLoopCountExpr->isValueDependent() &&
8310 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
8311 NestedLoopCount = Result.Val.getInt().getLimitedValue();
8312 } else {
8313 Built.clear(/*Size=*/1);
8314 return 1;
8315 }
8316 }
8317 unsigned OrderedLoopCount = 1;
8318 if (OrderedLoopCountExpr) {
8319 // Found 'ordered' clause - calculate collapse number.
8320 Expr::EvalResult EVResult;
8321 if (!OrderedLoopCountExpr->isValueDependent() &&
8322 OrderedLoopCountExpr->EvaluateAsInt(EVResult,
8323 SemaRef.getASTContext())) {
8324 llvm::APSInt Result = EVResult.Val.getInt();
8325 if (Result.getLimitedValue() < NestedLoopCount) {
8326 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8327 diag::err_omp_wrong_ordered_loop_count)
8328 << OrderedLoopCountExpr->getSourceRange();
8329 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8330 diag::note_collapse_loop_count)
8331 << CollapseLoopCountExpr->getSourceRange();
8332 }
8333 OrderedLoopCount = Result.getLimitedValue();
8334 } else {
8335 Built.clear(/*Size=*/1);
8336 return 1;
8337 }
8338 }
8339 // This is helper routine for loop directives (e.g., 'for', 'simd',
8340 // 'for simd', etc.).
8341 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8342 SmallVector<LoopIterationSpace, 4> IterSpaces(
8343 std::max(OrderedLoopCount, NestedLoopCount));
8344 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
8345 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
8346 if (checkOpenMPIterationSpace(
8347 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
8348 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
8349 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
8350 return 0;
8351 // Move on to the next nested for loop, or to the loop body.
8352 // OpenMP [2.8.1, simd construct, Restrictions]
8353 // All loops associated with the construct must be perfectly nested; that
8354 // is, there must be no intervening code nor any OpenMP directive between
8355 // any two loops.
8356 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
8357 CurStmt = For->getBody();
8358 } else {
8359 assert(isa<CXXForRangeStmt>(CurStmt) &&
8360 "Expected canonical for or range-based for loops.");
8361 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
8362 }
8363 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop(
8364 CurStmt, SemaRef.LangOpts.OpenMP >= 50);
8365 }
8366 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) {
8367 if (checkOpenMPIterationSpace(
8368 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
8369 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
8370 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
8371 return 0;
8372 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
8373 // Handle initialization of captured loop iterator variables.
8374 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
8375 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
8376 Captures[DRE] = DRE;
8377 }
8378 }
8379 // Move on to the next nested for loop, or to the loop body.
8380 // OpenMP [2.8.1, simd construct, Restrictions]
8381 // All loops associated with the construct must be perfectly nested; that
8382 // is, there must be no intervening code nor any OpenMP directive between
8383 // any two loops.
8384 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
8385 CurStmt = For->getBody();
8386 } else {
8387 assert(isa<CXXForRangeStmt>(CurStmt) &&
8388 "Expected canonical for or range-based for loops.");
8389 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
8390 }
8391 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop(
8392 CurStmt, SemaRef.LangOpts.OpenMP >= 50);
8393 }
8394
8395 Built.clear(/* size */ NestedLoopCount);
8396
8397 if (SemaRef.CurContext->isDependentContext())
8398 return NestedLoopCount;
8399
8400 // An example of what is generated for the following code:
8401 //
8402 // #pragma omp simd collapse(2) ordered(2)
8403 // for (i = 0; i < NI; ++i)
8404 // for (k = 0; k < NK; ++k)
8405 // for (j = J0; j < NJ; j+=2) {
8406 // <loop body>
8407 // }
8408 //
8409 // We generate the code below.
8410 // Note: the loop body may be outlined in CodeGen.
8411 // Note: some counters may be C++ classes, operator- is used to find number of
8412 // iterations and operator+= to calculate counter value.
8413 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
8414 // or i64 is currently supported).
8415 //
8416 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
8417 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
8418 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
8419 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
8420 // // similar updates for vars in clauses (e.g. 'linear')
8421 // <loop body (using local i and j)>
8422 // }
8423 // i = NI; // assign final values of counters
8424 // j = NJ;
8425 //
8426
8427 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
8428 // the iteration counts of the collapsed for loops.
8429 // Precondition tests if there is at least one iteration (all conditions are
8430 // true).
8431 auto PreCond = ExprResult(IterSpaces[0].PreCond);
8432 Expr *N0 = IterSpaces[0].NumIterations;
8433 ExprResult LastIteration32 =
8434 widenIterationCount(/*Bits=*/32,
8435 SemaRef
8436 .PerformImplicitConversion(
8437 N0->IgnoreImpCasts(), N0->getType(),
8438 Sema::AA_Converting, /*AllowExplicit=*/true)
8439 .get(),
8440 SemaRef);
8441 ExprResult LastIteration64 = widenIterationCount(
8442 /*Bits=*/64,
8443 SemaRef
8444 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
8445 Sema::AA_Converting,
8446 /*AllowExplicit=*/true)
8447 .get(),
8448 SemaRef);
8449
8450 if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
8451 return NestedLoopCount;
8452
8453 ASTContext &C = SemaRef.Context;
8454 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
8455
8456 Scope *CurScope = DSA.getCurScope();
8457 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
8458 if (PreCond.isUsable()) {
8459 PreCond =
8460 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
8461 PreCond.get(), IterSpaces[Cnt].PreCond);
8462 }
8463 Expr *N = IterSpaces[Cnt].NumIterations;
8464 SourceLocation Loc = N->getExprLoc();
8465 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
8466 if (LastIteration32.isUsable())
8467 LastIteration32 = SemaRef.BuildBinOp(
8468 CurScope, Loc, BO_Mul, LastIteration32.get(),
8469 SemaRef
8470 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
8471 Sema::AA_Converting,
8472 /*AllowExplicit=*/true)
8473 .get());
8474 if (LastIteration64.isUsable())
8475 LastIteration64 = SemaRef.BuildBinOp(
8476 CurScope, Loc, BO_Mul, LastIteration64.get(),
8477 SemaRef
8478 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
8479 Sema::AA_Converting,
8480 /*AllowExplicit=*/true)
8481 .get());
8482 }
8483
8484 // Choose either the 32-bit or 64-bit version.
8485 ExprResult LastIteration = LastIteration64;
8486 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
8487 (LastIteration32.isUsable() &&
8488 C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
8489 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
8490 fitsInto(
8491 /*Bits=*/32,
8492 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
8493 LastIteration64.get(), SemaRef))))
8494 LastIteration = LastIteration32;
8495 QualType VType = LastIteration.get()->getType();
8496 QualType RealVType = VType;
8497 QualType StrideVType = VType;
8498 if (isOpenMPTaskLoopDirective(DKind)) {
8499 VType =
8500 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
8501 StrideVType =
8502 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
8503 }
8504
8505 if (!LastIteration.isUsable())
8506 return 0;
8507
8508 // Save the number of iterations.
8509 ExprResult NumIterations = LastIteration;
8510 {
8511 LastIteration = SemaRef.BuildBinOp(
8512 CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
8513 LastIteration.get(),
8514 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8515 if (!LastIteration.isUsable())
8516 return 0;
8517 }
8518
8519 // Calculate the last iteration number beforehand instead of doing this on
8520 // each iteration. Do not do this if the number of iterations may be kfold-ed.
8521 bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
8522 ExprResult CalcLastIteration;
8523 if (!IsConstant) {
8524 ExprResult SaveRef =
8525 tryBuildCapture(SemaRef, LastIteration.get(), Captures);
8526 LastIteration = SaveRef;
8527
8528 // Prepare SaveRef + 1.
8529 NumIterations = SemaRef.BuildBinOp(
8530 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
8531 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8532 if (!NumIterations.isUsable())
8533 return 0;
8534 }
8535
8536 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
8537
8538 // Build variables passed into runtime, necessary for worksharing directives.
8539 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
8540 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
8541 isOpenMPDistributeDirective(DKind)) {
8542 // Lower bound variable, initialized with zero.
8543 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
8544 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
8545 SemaRef.AddInitializerToDecl(LBDecl,
8546 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8547 /*DirectInit*/ false);
8548
8549 // Upper bound variable, initialized with last iteration number.
8550 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
8551 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
8552 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
8553 /*DirectInit*/ false);
8554
8555 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
8556 // This will be used to implement clause 'lastprivate'.
8557 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
8558 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
8559 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
8560 SemaRef.AddInitializerToDecl(ILDecl,
8561 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8562 /*DirectInit*/ false);
8563
8564 // Stride variable returned by runtime (we initialize it to 1 by default).
8565 VarDecl *STDecl =
8566 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
8567 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
8568 SemaRef.AddInitializerToDecl(STDecl,
8569 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
8570 /*DirectInit*/ false);
8571
8572 // Build expression: UB = min(UB, LastIteration)
8573 // It is necessary for CodeGen of directives with static scheduling.
8574 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
8575 UB.get(), LastIteration.get());
8576 ExprResult CondOp = SemaRef.ActOnConditionalOp(
8577 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
8578 LastIteration.get(), UB.get());
8579 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
8580 CondOp.get());
8581 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
8582
8583 // If we have a combined directive that combines 'distribute', 'for' or
8584 // 'simd' we need to be able to access the bounds of the schedule of the
8585 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
8586 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
8587 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8588 // Lower bound variable, initialized with zero.
8589 VarDecl *CombLBDecl =
8590 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
8591 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
8592 SemaRef.AddInitializerToDecl(
8593 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8594 /*DirectInit*/ false);
8595
8596 // Upper bound variable, initialized with last iteration number.
8597 VarDecl *CombUBDecl =
8598 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
8599 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
8600 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
8601 /*DirectInit*/ false);
8602
8603 ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
8604 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
8605 ExprResult CombCondOp =
8606 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
8607 LastIteration.get(), CombUB.get());
8608 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
8609 CombCondOp.get());
8610 CombEUB =
8611 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
8612
8613 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
8614 // We expect to have at least 2 more parameters than the 'parallel'
8615 // directive does - the lower and upper bounds of the previous schedule.
8616 assert(CD->getNumParams() >= 4 &&
8617 "Unexpected number of parameters in loop combined directive");
8618
8619 // Set the proper type for the bounds given what we learned from the
8620 // enclosed loops.
8621 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
8622 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
8623
8624 // Previous lower and upper bounds are obtained from the region
8625 // parameters.
8626 PrevLB =
8627 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
8628 PrevUB =
8629 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
8630 }
8631 }
8632
8633 // Build the iteration variable and its initialization before loop.
8634 ExprResult IV;
8635 ExprResult Init, CombInit;
8636 {
8637 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
8638 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
8639 Expr *RHS =
8640 (isOpenMPWorksharingDirective(DKind) ||
8641 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
8642 ? LB.get()
8643 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
8644 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
8645 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
8646
8647 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8648 Expr *CombRHS =
8649 (isOpenMPWorksharingDirective(DKind) ||
8650 isOpenMPTaskLoopDirective(DKind) ||
8651 isOpenMPDistributeDirective(DKind))
8652 ? CombLB.get()
8653 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
8654 CombInit =
8655 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
8656 CombInit =
8657 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
8658 }
8659 }
8660
8661 bool UseStrictCompare =
8662 RealVType->hasUnsignedIntegerRepresentation() &&
8663 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
8664 return LIS.IsStrictCompare;
8665 });
8666 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
8667 // unsigned IV)) for worksharing loops.
8668 SourceLocation CondLoc = AStmt->getBeginLoc();
8669 Expr *BoundUB = UB.get();
8670 if (UseStrictCompare) {
8671 BoundUB =
8672 SemaRef
8673 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
8674 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8675 .get();
8676 BoundUB =
8677 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
8678 }
8679 ExprResult Cond =
8680 (isOpenMPWorksharingDirective(DKind) ||
8681 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
8682 ? SemaRef.BuildBinOp(CurScope, CondLoc,
8683 UseStrictCompare ? BO_LT : BO_LE, IV.get(),
8684 BoundUB)
8685 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
8686 NumIterations.get());
8687 ExprResult CombDistCond;
8688 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8689 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
8690 NumIterations.get());
8691 }
8692
8693 ExprResult CombCond;
8694 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8695 Expr *BoundCombUB = CombUB.get();
8696 if (UseStrictCompare) {
8697 BoundCombUB =
8698 SemaRef
8699 .BuildBinOp(
8700 CurScope, CondLoc, BO_Add, BoundCombUB,
8701 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8702 .get();
8703 BoundCombUB =
8704 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
8705 .get();
8706 }
8707 CombCond =
8708 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
8709 IV.get(), BoundCombUB);
8710 }
8711 // Loop increment (IV = IV + 1)
8712 SourceLocation IncLoc = AStmt->getBeginLoc();
8713 ExprResult Inc =
8714 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
8715 SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
8716 if (!Inc.isUsable())
8717 return 0;
8718 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
8719 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
8720 if (!Inc.isUsable())
8721 return 0;
8722
8723 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
8724 // Used for directives with static scheduling.
8725 // In combined construct, add combined version that use CombLB and CombUB
8726 // base variables for the update
8727 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
8728 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
8729 isOpenMPDistributeDirective(DKind)) {
8730 // LB + ST
8731 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
8732 if (!NextLB.isUsable())
8733 return 0;
8734 // LB = LB + ST
8735 NextLB =
8736 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
8737 NextLB =
8738 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
8739 if (!NextLB.isUsable())
8740 return 0;
8741 // UB + ST
8742 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
8743 if (!NextUB.isUsable())
8744 return 0;
8745 // UB = UB + ST
8746 NextUB =
8747 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
8748 NextUB =
8749 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
8750 if (!NextUB.isUsable())
8751 return 0;
8752 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8753 CombNextLB =
8754 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
8755 if (!NextLB.isUsable())
8756 return 0;
8757 // LB = LB + ST
8758 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
8759 CombNextLB.get());
8760 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
8761 /*DiscardedValue*/ false);
8762 if (!CombNextLB.isUsable())
8763 return 0;
8764 // UB + ST
8765 CombNextUB =
8766 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
8767 if (!CombNextUB.isUsable())
8768 return 0;
8769 // UB = UB + ST
8770 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
8771 CombNextUB.get());
8772 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
8773 /*DiscardedValue*/ false);
8774 if (!CombNextUB.isUsable())
8775 return 0;
8776 }
8777 }
8778
8779 // Create increment expression for distribute loop when combined in a same
8780 // directive with for as IV = IV + ST; ensure upper bound expression based
8781 // on PrevUB instead of NumIterations - used to implement 'for' when found
8782 // in combination with 'distribute', like in 'distribute parallel for'
8783 SourceLocation DistIncLoc = AStmt->getBeginLoc();
8784 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
8785 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8786 DistCond = SemaRef.BuildBinOp(
8787 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
8788 assert(DistCond.isUsable() && "distribute cond expr was not built");
8789
8790 DistInc =
8791 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
8792 assert(DistInc.isUsable() && "distribute inc expr was not built");
8793 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
8794 DistInc.get());
8795 DistInc =
8796 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
8797 assert(DistInc.isUsable() && "distribute inc expr was not built");
8798
8799 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
8800 // construct
8801 SourceLocation DistEUBLoc = AStmt->getBeginLoc();
8802 ExprResult IsUBGreater =
8803 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
8804 ExprResult CondOp = SemaRef.ActOnConditionalOp(
8805 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
8806 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
8807 CondOp.get());
8808 PrevEUB =
8809 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
8810
8811 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
8812 // parallel for is in combination with a distribute directive with
8813 // schedule(static, 1)
8814 Expr *BoundPrevUB = PrevUB.get();
8815 if (UseStrictCompare) {
8816 BoundPrevUB =
8817 SemaRef
8818 .BuildBinOp(
8819 CurScope, CondLoc, BO_Add, BoundPrevUB,
8820 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8821 .get();
8822 BoundPrevUB =
8823 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
8824 .get();
8825 }
8826 ParForInDistCond =
8827 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
8828 IV.get(), BoundPrevUB);
8829 }
8830
8831 // Build updates and final values of the loop counters.
8832 bool HasErrors = false;
8833 Built.Counters.resize(NestedLoopCount);
8834 Built.Inits.resize(NestedLoopCount);
8835 Built.Updates.resize(NestedLoopCount);
8836 Built.Finals.resize(NestedLoopCount);
8837 Built.DependentCounters.resize(NestedLoopCount);
8838 Built.DependentInits.resize(NestedLoopCount);
8839 Built.FinalsConditions.resize(NestedLoopCount);
8840 {
8841 // We implement the following algorithm for obtaining the
8842 // original loop iteration variable values based on the
8843 // value of the collapsed loop iteration variable IV.
8844 //
8845 // Let n+1 be the number of collapsed loops in the nest.
8846 // Iteration variables (I0, I1, .... In)
8847 // Iteration counts (N0, N1, ... Nn)
8848 //
8849 // Acc = IV;
8850 //
8851 // To compute Ik for loop k, 0 <= k <= n, generate:
8852 // Prod = N(k+1) * N(k+2) * ... * Nn;
8853 // Ik = Acc / Prod;
8854 // Acc -= Ik * Prod;
8855 //
8856 ExprResult Acc = IV;
8857 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
8858 LoopIterationSpace &IS = IterSpaces[Cnt];
8859 SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
8860 ExprResult Iter;
8861
8862 // Compute prod
8863 ExprResult Prod =
8864 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
8865 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
8866 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
8867 IterSpaces[K].NumIterations);
8868
8869 // Iter = Acc / Prod
8870 // If there is at least one more inner loop to avoid
8871 // multiplication by 1.
8872 if (Cnt + 1 < NestedLoopCount)
8873 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
8874 Acc.get(), Prod.get());
8875 else
8876 Iter = Acc;
8877 if (!Iter.isUsable()) {
8878 HasErrors = true;
8879 break;
8880 }
8881
8882 // Update Acc:
8883 // Acc -= Iter * Prod
8884 // Check if there is at least one more inner loop to avoid
8885 // multiplication by 1.
8886 if (Cnt + 1 < NestedLoopCount)
8887 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
8888 Iter.get(), Prod.get());
8889 else
8890 Prod = Iter;
8891 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
8892 Acc.get(), Prod.get());
8893
8894 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
8895 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
8896 DeclRefExpr *CounterVar = buildDeclRefExpr(
8897 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
8898 /*RefersToCapture=*/true);
8899 ExprResult Init =
8900 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
8901 IS.CounterInit, IS.IsNonRectangularLB, Captures);
8902 if (!Init.isUsable()) {
8903 HasErrors = true;
8904 break;
8905 }
8906 ExprResult Update = buildCounterUpdate(
8907 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
8908 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
8909 if (!Update.isUsable()) {
8910 HasErrors = true;
8911 break;
8912 }
8913
8914 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
8915 ExprResult Final =
8916 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
8917 IS.CounterInit, IS.NumIterations, IS.CounterStep,
8918 IS.Subtract, IS.IsNonRectangularLB, &Captures);
8919 if (!Final.isUsable()) {
8920 HasErrors = true;
8921 break;
8922 }
8923
8924 if (!Update.isUsable() || !Final.isUsable()) {
8925 HasErrors = true;
8926 break;
8927 }
8928 // Save results
8929 Built.Counters[Cnt] = IS.CounterVar;
8930 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
8931 Built.Inits[Cnt] = Init.get();
8932 Built.Updates[Cnt] = Update.get();
8933 Built.Finals[Cnt] = Final.get();
8934 Built.DependentCounters[Cnt] = nullptr;
8935 Built.DependentInits[Cnt] = nullptr;
8936 Built.FinalsConditions[Cnt] = nullptr;
8937 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
8938 Built.DependentCounters[Cnt] =
8939 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
8940 Built.DependentInits[Cnt] =
8941 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
8942 Built.FinalsConditions[Cnt] = IS.FinalCondition;
8943 }
8944 }
8945 }
8946
8947 if (HasErrors)
8948 return 0;
8949
8950 // Save results
8951 Built.IterationVarRef = IV.get();
8952 Built.LastIteration = LastIteration.get();
8953 Built.NumIterations = NumIterations.get();
8954 Built.CalcLastIteration = SemaRef
8955 .ActOnFinishFullExpr(CalcLastIteration.get(),
8956 /*DiscardedValue=*/false)
8957 .get();
8958 Built.PreCond = PreCond.get();
8959 Built.PreInits = buildPreInits(C, Captures);
8960 Built.Cond = Cond.get();
8961 Built.Init = Init.get();
8962 Built.Inc = Inc.get();
8963 Built.LB = LB.get();
8964 Built.UB = UB.get();
8965 Built.IL = IL.get();
8966 Built.ST = ST.get();
8967 Built.EUB = EUB.get();
8968 Built.NLB = NextLB.get();
8969 Built.NUB = NextUB.get();
8970 Built.PrevLB = PrevLB.get();
8971 Built.PrevUB = PrevUB.get();
8972 Built.DistInc = DistInc.get();
8973 Built.PrevEUB = PrevEUB.get();
8974 Built.DistCombinedFields.LB = CombLB.get();
8975 Built.DistCombinedFields.UB = CombUB.get();
8976 Built.DistCombinedFields.EUB = CombEUB.get();
8977 Built.DistCombinedFields.Init = CombInit.get();
8978 Built.DistCombinedFields.Cond = CombCond.get();
8979 Built.DistCombinedFields.NLB = CombNextLB.get();
8980 Built.DistCombinedFields.NUB = CombNextUB.get();
8981 Built.DistCombinedFields.DistCond = CombDistCond.get();
8982 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
8983
8984 return NestedLoopCount;
8985}
8986
8987static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
8988 auto CollapseClauses =
8989 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
8990 if (CollapseClauses.begin() != CollapseClauses.end())
8991 return (*CollapseClauses.begin())->getNumForLoops();
8992 return nullptr;
8993}
8994
8995static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
8996 auto OrderedClauses =
8997 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
8998 if (OrderedClauses.begin() != OrderedClauses.end())
8999 return (*OrderedClauses.begin())->getNumForLoops();
9000 return nullptr;
9001}
9002
9003static bool checkSimdlenSafelenSpecified(Sema &S,
9004 const ArrayRef<OMPClause *> Clauses) {
9005 const OMPSafelenClause *Safelen = nullptr;
9006 const OMPSimdlenClause *Simdlen = nullptr;
9007
9008 for (const OMPClause *Clause : Clauses) {
9009 if (Clause->getClauseKind() == OMPC_safelen)
9010 Safelen = cast<OMPSafelenClause>(Clause);
9011 else if (Clause->getClauseKind() == OMPC_simdlen)
9012 Simdlen = cast<OMPSimdlenClause>(Clause);
9013 if (Safelen && Simdlen)
9014 break;
9015 }
9016
9017 if (Simdlen && Safelen) {
9018 const Expr *SimdlenLength = Simdlen->getSimdlen();
9019 const Expr *SafelenLength = Safelen->getSafelen();
9020 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
9021 SimdlenLength->isInstantiationDependent() ||
9022 SimdlenLength->containsUnexpandedParameterPack())
9023 return false;
9024 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
9025 SafelenLength->isInstantiationDependent() ||
9026 SafelenLength->containsUnexpandedParameterPack())
9027 return false;
9028 Expr::EvalResult SimdlenResult, SafelenResult;
9029 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
9030 SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
9031 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
9032 llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
9033 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
9034 // If both simdlen and safelen clauses are specified, the value of the
9035 // simdlen parameter must be less than or equal to the value of the safelen
9036 // parameter.
9037 if (SimdlenRes > SafelenRes) {
9038 S.Diag(SimdlenLength->getExprLoc(),
9039 diag::err_omp_wrong_simdlen_safelen_values)
9040 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
9041 return true;
9042 }
9043 }
9044 return false;
9045}
9046
9047StmtResult
9048Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9049 SourceLocation StartLoc, SourceLocation EndLoc,
9050 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9051 if (!AStmt)
9052 return StmtError();
9053
9054 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9055 OMPLoopDirective::HelperExprs B;
9056 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9057 // define the nested loops number.
9058 unsigned NestedLoopCount = checkOpenMPLoop(
9059 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9060 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
9061 if (NestedLoopCount == 0)
9062 return StmtError();
9063
9064 assert((CurContext->isDependentContext() || B.builtAll()) &&
9065 "omp simd loop exprs were not built");
9066
9067 if (!CurContext->isDependentContext()) {
9068 // Finalize the clauses that need pre-built expressions for CodeGen.
9069 for (OMPClause *C : Clauses) {
9070 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9071 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9072 B.NumIterations, *this, CurScope,
9073 DSAStack))
9074 return StmtError();
9075 }
9076 }
9077
9078 if (checkSimdlenSafelenSpecified(*this, Clauses))
9079 return StmtError();
9080
9081 setFunctionHasBranchProtectedScope();
9082 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9083 Clauses, AStmt, B);
9084}
9085
9086StmtResult
9087Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9088 SourceLocation StartLoc, SourceLocation EndLoc,
9089 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9090 if (!AStmt)
9091 return StmtError();
9092
9093 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9094 OMPLoopDirective::HelperExprs B;
9095 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9096 // define the nested loops number.
9097 unsigned NestedLoopCount = checkOpenMPLoop(
9098 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9099 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
9100 if (NestedLoopCount == 0)
9101 return StmtError();
9102
9103 assert((CurContext->isDependentContext() || B.builtAll()) &&
9104 "omp for loop exprs were not built");
9105
9106 if (!CurContext->isDependentContext()) {
9107 // Finalize the clauses that need pre-built expressions for CodeGen.
9108 for (OMPClause *C : Clauses) {
9109 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9110 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9111 B.NumIterations, *this, CurScope,
9112 DSAStack))
9113 return StmtError();
9114 }
9115 }
9116
9117 setFunctionHasBranchProtectedScope();
9118 return OMPForDirective::Create(
9119 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9120 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
9121}
9122
9123StmtResult Sema::ActOnOpenMPForSimdDirective(
9124 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9125 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9126 if (!AStmt)
9127 return StmtError();
9128
9129 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9130 OMPLoopDirective::HelperExprs B;
9131 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9132 // define the nested loops number.
9133 unsigned NestedLoopCount =
9134 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
9135 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
9136 VarsWithImplicitDSA, B);
9137 if (NestedLoopCount == 0)
9138 return StmtError();
9139
9140 assert((CurContext->isDependentContext() || B.builtAll()) &&
9141 "omp for simd loop exprs were not built");
9142
9143 if (!CurContext->isDependentContext()) {
9144 // Finalize the clauses that need pre-built expressions for CodeGen.
9145 for (OMPClause *C : Clauses) {
9146 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9147 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9148 B.NumIterations, *this, CurScope,
9149 DSAStack))
9150 return StmtError();
9151 }
9152 }
9153
9154 if (checkSimdlenSafelenSpecified(*this, Clauses))
9155 return StmtError();
9156
9157 setFunctionHasBranchProtectedScope();
9158 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9159 Clauses, AStmt, B);
9160}
9161
9162StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
9163 Stmt *AStmt,
9164 SourceLocation StartLoc,
9165 SourceLocation EndLoc) {
9166 if (!AStmt)
9167 return StmtError();
9168
9169 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9170 auto BaseStmt = AStmt;
9171 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
9172 BaseStmt = CS->getCapturedStmt();
9173 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
9174 auto S = C->children();
9175 if (S.begin() == S.end())
9176 return StmtError();
9177 // All associated statements must be '#pragma omp section' except for
9178 // the first one.
9179 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
9180 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
9181 if (SectionStmt)
9182 Diag(SectionStmt->getBeginLoc(),
9183 diag::err_omp_sections_substmt_not_section);
9184 return StmtError();
9185 }
9186 cast<OMPSectionDirective>(SectionStmt)
9187 ->setHasCancel(DSAStack->isCancelRegion());
9188 }
9189 } else {
9190 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
9191 return StmtError();
9192 }
9193
9194 setFunctionHasBranchProtectedScope();
9195
9196 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9197 DSAStack->getTaskgroupReductionRef(),
9198 DSAStack->isCancelRegion());
9199}
9200
9201StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
9202 SourceLocation StartLoc,
9203 SourceLocation EndLoc) {
9204 if (!AStmt)
9205 return StmtError();
9206
9207 setFunctionHasBranchProtectedScope();
9208 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
9209
9210 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
9211 DSAStack->isCancelRegion());
9212}
9213
9214StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
9215 Stmt *AStmt,
9216 SourceLocation StartLoc,
9217 SourceLocation EndLoc) {
9218 if (!AStmt)
9219 return StmtError();
9220
9221 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9222
9223 setFunctionHasBranchProtectedScope();
9224
9225 // OpenMP [2.7.3, single Construct, Restrictions]
9226 // The copyprivate clause must not be used with the nowait clause.
9227 const OMPClause *Nowait = nullptr;
9228 const OMPClause *Copyprivate = nullptr;
9229 for (const OMPClause *Clause : Clauses) {
9230 if (Clause->getClauseKind() == OMPC_nowait)
9231 Nowait = Clause;
9232 else if (Clause->getClauseKind() == OMPC_copyprivate)
9233 Copyprivate = Clause;
9234 if (Copyprivate && Nowait) {
9235 Diag(Copyprivate->getBeginLoc(),
9236 diag::err_omp_single_copyprivate_with_nowait);
9237 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
9238 return StmtError();
9239 }
9240 }
9241
9242 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9243}
9244
9245StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
9246 SourceLocation StartLoc,
9247 SourceLocation EndLoc) {
9248 if (!AStmt)
9249 return StmtError();
9250
9251 setFunctionHasBranchProtectedScope();
9252
9253 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
9254}
9255
9256StmtResult Sema::ActOnOpenMPCriticalDirective(
9257 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
9258 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
9259 if (!AStmt)
9260 return StmtError();
9261
9262 bool ErrorFound = false;
9263 llvm::APSInt Hint;
9264 SourceLocation HintLoc;
9265 bool DependentHint = false;
9266 for (const OMPClause *C : Clauses) {
9267 if (C->getClauseKind() == OMPC_hint) {
9268 if (!DirName.getName()) {
9269 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
9270 ErrorFound = true;
9271 }
9272 Expr *E = cast<OMPHintClause>(C)->getHint();
9273 if (E->isTypeDependent() || E->isValueDependent() ||
9274 E->isInstantiationDependent()) {
9275 DependentHint = true;
9276 } else {
9277 Hint = E->EvaluateKnownConstInt(Context);
9278 HintLoc = C->getBeginLoc();
9279 }
9280 }
9281 }
9282 if (ErrorFound)
9283 return StmtError();
9284 const auto Pair = DSAStack->getCriticalWithHint(DirName);
9285 if (Pair.first && DirName.getName() && !DependentHint) {
9286 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
9287 Diag(StartLoc, diag::err_omp_critical_with_hint);
9288 if (HintLoc.isValid())
9289 Diag(HintLoc, diag::note_omp_critical_hint_here)
9290 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
9291 else
9292 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
9293 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
9294 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
9295 << 1
9296 << C->getHint()->EvaluateKnownConstInt(Context).toString(
9297 /*Radix=*/10, /*Signed=*/false);
9298 } else {
9299 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
9300 }
9301 }
9302 }
9303
9304 setFunctionHasBranchProtectedScope();
9305
9306 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
9307 Clauses, AStmt);
9308 if (!Pair.first && DirName.getName() && !DependentHint)
9309 DSAStack->addCriticalWithHint(Dir, Hint);
9310 return Dir;
9311}
9312
9313StmtResult Sema::ActOnOpenMPParallelForDirective(
9314 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9315 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9316 if (!AStmt)
9317 return StmtError();
9318
9319 auto *CS = cast<CapturedStmt>(AStmt);
9320 // 1.2.2 OpenMP Language Terminology
9321 // Structured block - An executable statement with a single entry at the
9322 // top and a single exit at the bottom.
9323 // The point of exit cannot be a branch out of the structured block.
9324 // longjmp() and throw() must not violate the entry/exit criteria.
9325 CS->getCapturedDecl()->setNothrow();
9326
9327 OMPLoopDirective::HelperExprs B;
9328 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9329 // define the nested loops number.
9330 unsigned NestedLoopCount =
9331 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
9332 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
9333 VarsWithImplicitDSA, B);
9334 if (NestedLoopCount == 0)
9335 return StmtError();
9336
9337 assert((CurContext->isDependentContext() || B.builtAll()) &&
9338 "omp parallel for loop exprs were not built");
9339
9340 if (!CurContext->isDependentContext()) {
9341 // Finalize the clauses that need pre-built expressions for CodeGen.
9342 for (OMPClause *C : Clauses) {
9343 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9344 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9345 B.NumIterations, *this, CurScope,
9346 DSAStack))
9347 return StmtError();
9348 }
9349 }
9350
9351 setFunctionHasBranchProtectedScope();
9352 return OMPParallelForDirective::Create(
9353 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9354 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
9355}
9356
9357StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
9358 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9359 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9360 if (!AStmt)
9361 return StmtError();
9362
9363 auto *CS = cast<CapturedStmt>(AStmt);
9364 // 1.2.2 OpenMP Language Terminology
9365 // Structured block - An executable statement with a single entry at the
9366 // top and a single exit at the bottom.
9367 // The point of exit cannot be a branch out of the structured block.
9368 // longjmp() and throw() must not violate the entry/exit criteria.
9369 CS->getCapturedDecl()->setNothrow();
9370
9371 OMPLoopDirective::HelperExprs B;
9372 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9373 // define the nested loops number.
9374 unsigned NestedLoopCount =
9375 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
9376 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
9377 VarsWithImplicitDSA, B);
9378 if (NestedLoopCount == 0)
9379 return StmtError();
9380
9381 if (!CurContext->isDependentContext()) {
9382 // Finalize the clauses that need pre-built expressions for CodeGen.
9383 for (OMPClause *C : Clauses) {
9384 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9385 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9386 B.NumIterations, *this, CurScope,
9387 DSAStack))
9388 return StmtError();
9389 }
9390 }
9391
9392 if (checkSimdlenSafelenSpecified(*this, Clauses))
9393 return StmtError();
9394
9395 setFunctionHasBranchProtectedScope();
9396 return OMPParallelForSimdDirective::Create(
9397 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9398}
9399
9400StmtResult
9401Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
9402 Stmt *AStmt, SourceLocation StartLoc,
9403 SourceLocation EndLoc) {
9404 if (!AStmt)
9405 return StmtError();
9406
9407 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9408 auto *CS = cast<CapturedStmt>(AStmt);
9409 // 1.2.2 OpenMP Language Terminology
9410 // Structured block - An executable statement with a single entry at the
9411 // top and a single exit at the bottom.
9412 // The point of exit cannot be a branch out of the structured block.
9413 // longjmp() and throw() must not violate the entry/exit criteria.
9414 CS->getCapturedDecl()->setNothrow();
9415
9416 setFunctionHasBranchProtectedScope();
9417
9418 return OMPParallelMasterDirective::Create(
9419 Context, StartLoc, EndLoc, Clauses, AStmt,
9420 DSAStack->getTaskgroupReductionRef());
9421}
9422
9423StmtResult
9424Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
9425 Stmt *AStmt, SourceLocation StartLoc,
9426 SourceLocation EndLoc) {
9427 if (!AStmt)
9428 return StmtError();
9429
9430 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9431 auto BaseStmt = AStmt;
9432 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
9433 BaseStmt = CS->getCapturedStmt();
9434 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
9435 auto S = C->children();
9436 if (S.begin() == S.end())
9437 return StmtError();
9438 // All associated statements must be '#pragma omp section' except for
9439 // the first one.
9440 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
9441 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
9442 if (SectionStmt)
9443 Diag(SectionStmt->getBeginLoc(),
9444 diag::err_omp_parallel_sections_substmt_not_section);
9445 return StmtError();
9446 }
9447 cast<OMPSectionDirective>(SectionStmt)
9448 ->setHasCancel(DSAStack->isCancelRegion());
9449 }
9450 } else {
9451 Diag(AStmt->getBeginLoc(),
9452 diag::err_omp_parallel_sections_not_compound_stmt);
9453 return StmtError();
9454 }
9455
9456 setFunctionHasBranchProtectedScope();
9457
9458 return OMPParallelSectionsDirective::Create(
9459 Context, StartLoc, EndLoc, Clauses, AStmt,
9460 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
9461}
9462
9463/// detach and mergeable clauses are mutially exclusive, check for it.
9464static bool checkDetachMergeableClauses(Sema &S,
9465 ArrayRef<OMPClause *> Clauses) {
9466 const OMPClause *PrevClause = nullptr;
9467 bool ErrorFound = false;
9468 for (const OMPClause *C : Clauses) {
9469 if (C->getClauseKind() == OMPC_detach ||
9470 C->getClauseKind() == OMPC_mergeable) {
9471 if (!PrevClause) {
9472 PrevClause = C;
9473 } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
9474 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
9475 << getOpenMPClauseName(C->getClauseKind())
9476 << getOpenMPClauseName(PrevClause->getClauseKind());
9477 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
9478 << getOpenMPClauseName(PrevClause->getClauseKind());
9479 ErrorFound = true;
9480 }
9481 }
9482 }
9483 return ErrorFound;
9484}
9485
9486StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
9487 Stmt *AStmt, SourceLocation StartLoc,
9488 SourceLocation EndLoc) {
9489 if (!AStmt)
9490 return StmtError();
9491
9492 // OpenMP 5.0, 2.10.1 task Construct
9493 // If a detach clause appears on the directive, then a mergeable clause cannot
9494 // appear on the same directive.
9495 if (checkDetachMergeableClauses(*this, Clauses))
9496 return StmtError();
9497
9498 auto *CS = cast<CapturedStmt>(AStmt);
9499 // 1.2.2 OpenMP Language Terminology
9500 // Structured block - An executable statement with a single entry at the
9501 // top and a single exit at the bottom.
9502 // The point of exit cannot be a branch out of the structured block.
9503 // longjmp() and throw() must not violate the entry/exit criteria.
9504 CS->getCapturedDecl()->setNothrow();
9505
9506 setFunctionHasBranchProtectedScope();
9507
9508 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9509 DSAStack->isCancelRegion());
9510}
9511
9512StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
9513 SourceLocation EndLoc) {
9514 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
9515}
9516
9517StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
9518 SourceLocation EndLoc) {
9519 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
9520}
9521
9522StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
9523 SourceLocation EndLoc) {
9524 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
9525}
9526
9527StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
9528 Stmt *AStmt,
9529 SourceLocation StartLoc,
9530 SourceLocation EndLoc) {
9531 if (!AStmt)
9532 return StmtError();
9533
9534 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9535
9536 setFunctionHasBranchProtectedScope();
9537
9538 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
9539 AStmt,
9540 DSAStack->getTaskgroupReductionRef());
9541}
9542
9543StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
9544 SourceLocation StartLoc,
9545 SourceLocation EndLoc) {
9546 OMPFlushClause *FC = nullptr;
9547 OMPClause *OrderClause = nullptr;
9548 for (OMPClause *C : Clauses) {
9549 if (C->getClauseKind() == OMPC_flush)
9550 FC = cast<OMPFlushClause>(C);
9551 else
9552 OrderClause = C;
9553 }
9554 OpenMPClauseKind MemOrderKind = OMPC_unknown;
9555 SourceLocation MemOrderLoc;
9556 for (const OMPClause *C : Clauses) {
9557 if (C->getClauseKind() == OMPC_acq_rel ||
9558 C->getClauseKind() == OMPC_acquire ||
9559 C->getClauseKind() == OMPC_release) {
9560 if (MemOrderKind != OMPC_unknown) {
9561 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
9562 << getOpenMPDirectiveName(OMPD_flush) << 1
9563 << SourceRange(C->getBeginLoc(), C->getEndLoc());
9564 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
9565 << getOpenMPClauseName(MemOrderKind);
9566 } else {
9567 MemOrderKind = C->getClauseKind();
9568 MemOrderLoc = C->getBeginLoc();
9569 }
9570 }
9571 }
9572 if (FC && OrderClause) {
9573 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
9574 << getOpenMPClauseName(OrderClause->getClauseKind());
9575 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
9576 << getOpenMPClauseName(OrderClause->getClauseKind());
9577 return StmtError();
9578 }
9579 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
9580}
9581
9582StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
9583 SourceLocation StartLoc,
9584 SourceLocation EndLoc) {
9585 if (Clauses.empty()) {
9586 Diag(StartLoc, diag::err_omp_depobj_expected);
9587 return StmtError();
9588 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
9589 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
9590 return StmtError();
9591 }
9592 // Only depobj expression and another single clause is allowed.
9593 if (Clauses.size() > 2) {
9594 Diag(Clauses[2]->getBeginLoc(),
9595 diag::err_omp_depobj_single_clause_expected);
9596 return StmtError();
9597 } else if (Clauses.size() < 1) {
9598 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
9599 return StmtError();
9600 }
9601 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
9602}
9603
9604StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
9605 SourceLocation StartLoc,
9606 SourceLocation EndLoc) {
9607 // Check that exactly one clause is specified.
9608 if (Clauses.size() != 1) {
9609 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
9610 diag::err_omp_scan_single_clause_expected);
9611 return StmtError();
9612 }
9613 // Check that scan directive is used in the scopeof the OpenMP loop body.
9614 if (Scope *S = DSAStack->getCurScope()) {
9615 Scope *ParentS = S->getParent();
9616 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
9617 !ParentS->getBreakParent()->isOpenMPLoopScope())
9618 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
9619 << getOpenMPDirectiveName(OMPD_scan) << 5);
9620 }
9621 // Check that only one instance of scan directives is used in the same outer
9622 // region.
9623 if (DSAStack->doesParentHasScanDirective()) {
9624 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
9625 Diag(DSAStack->getParentScanDirectiveLoc(),
9626 diag::note_omp_previous_directive)
9627 << "scan";
9628 return StmtError();
9629 }
9630 DSAStack->setParentHasScanDirective(StartLoc);
9631 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
9632}
9633
9634StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
9635 Stmt *AStmt,
9636 SourceLocation StartLoc,
9637 SourceLocation EndLoc) {
9638 const OMPClause *DependFound = nullptr;
9639 const OMPClause *DependSourceClause = nullptr;
9640 const OMPClause *DependSinkClause = nullptr;
9641 bool ErrorFound = false;
9642 const OMPThreadsClause *TC = nullptr;
9643 const OMPSIMDClause *SC = nullptr;
9644 for (const OMPClause *C : Clauses) {
9645 if (auto *DC = dyn_cast<OMPDependClause>(C)) {
9646 DependFound = C;
9647 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
9648 if (DependSourceClause) {
9649 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
9650 << getOpenMPDirectiveName(OMPD_ordered)
9651 << getOpenMPClauseName(OMPC_depend) << 2;
9652 ErrorFound = true;
9653 } else {
9654 DependSourceClause = C;
9655 }
9656 if (DependSinkClause) {
9657 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
9658 << 0;
9659 ErrorFound = true;
9660 }
9661 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
9662 if (DependSourceClause) {
9663 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
9664 << 1;
9665 ErrorFound = true;
9666 }
9667 DependSinkClause = C;
9668 }
9669 } else if (C->getClauseKind() == OMPC_threads) {
9670 TC = cast<OMPThreadsClause>(C);
9671 } else if (C->getClauseKind() == OMPC_simd) {
9672 SC = cast<OMPSIMDClause>(C);
9673 }
9674 }
9675 if (!ErrorFound && !SC &&
9676 isOpenMPSimdDirective(DSAStack->getParentDirective())) {
9677 // OpenMP [2.8.1,simd Construct, Restrictions]
9678 // An ordered construct with the simd clause is the only OpenMP construct
9679 // that can appear in the simd region.
9680 Diag(StartLoc, diag::err_omp_prohibited_region_simd)
9681 << (LangOpts.OpenMP >= 50 ? 1 : 0);
9682 ErrorFound = true;
9683 } else if (DependFound && (TC || SC)) {
9684 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
9685 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
9686 ErrorFound = true;
9687 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) {
9688 Diag(DependFound->getBeginLoc(),
9689 diag::err_omp_ordered_directive_without_param);
9690 ErrorFound = true;
9691 } else if (TC || Clauses.empty()) {
9692 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
9693 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
9694 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
9695 << (TC != nullptr);
9696 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
9697 ErrorFound = true;
9698 }
9699 }
9700 if ((!AStmt && !DependFound) || ErrorFound)
9701 return StmtError();
9702
9703 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
9704 // During execution of an iteration of a worksharing-loop or a loop nest
9705 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
9706 // must not execute more than one ordered region corresponding to an ordered
9707 // construct without a depend clause.
9708 if (!DependFound) {
9709 if (DSAStack->doesParentHasOrderedDirective()) {
9710 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
9711 Diag(DSAStack->getParentOrderedDirectiveLoc(),
9712 diag::note_omp_previous_directive)
9713 << "ordered";
9714 return StmtError();
9715 }
9716 DSAStack->setParentHasOrderedDirective(StartLoc);
9717 }
9718
9719 if (AStmt) {
9720 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9721
9722 setFunctionHasBranchProtectedScope();
9723 }
9724
9725 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9726}
9727
9728namespace {
9729/// Helper class for checking expression in 'omp atomic [update]'
9730/// construct.
9731class OpenMPAtomicUpdateChecker {
9732 /// Error results for atomic update expressions.
9733 enum ExprAnalysisErrorCode {
9734 /// A statement is not an expression statement.
9735 NotAnExpression,
9736 /// Expression is not builtin binary or unary operation.
9737 NotABinaryOrUnaryExpression,
9738 /// Unary operation is not post-/pre- increment/decrement operation.
9739 NotAnUnaryIncDecExpression,
9740 /// An expression is not of scalar type.
9741 NotAScalarType,
9742 /// A binary operation is not an assignment operation.
9743 NotAnAssignmentOp,
9744 /// RHS part of the binary operation is not a binary expression.
9745 NotABinaryExpression,
9746 /// RHS part is not additive/multiplicative/shift/biwise binary
9747 /// expression.
9748 NotABinaryOperator,
9749 /// RHS binary operation does not have reference to the updated LHS
9750 /// part.
9751 NotAnUpdateExpression,
9752 /// No errors is found.
9753 NoError
9754 };
9755 /// Reference to Sema.
9756 Sema &SemaRef;
9757 /// A location for note diagnostics (when error is found).
9758 SourceLocation NoteLoc;
9759 /// 'x' lvalue part of the source atomic expression.
9760 Expr *X;
9761 /// 'expr' rvalue part of the source atomic expression.
9762 Expr *E;
9763 /// Helper expression of the form
9764 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
9765 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
9766 Expr *UpdateExpr;
9767 /// Is 'x' a LHS in a RHS part of full update expression. It is
9768 /// important for non-associative operations.
9769 bool IsXLHSInRHSPart;
9770 BinaryOperatorKind Op;
9771 SourceLocation OpLoc;
9772 /// true if the source expression is a postfix unary operation, false
9773 /// if it is a prefix unary operation.
9774 bool IsPostfixUpdate;
9775
9776public:
9777 OpenMPAtomicUpdateChecker(Sema &SemaRef)
9778 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
9779 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
9780 /// Check specified statement that it is suitable for 'atomic update'
9781 /// constructs and extract 'x', 'expr' and Operation from the original
9782 /// expression. If DiagId and NoteId == 0, then only check is performed
9783 /// without error notification.
9784 /// \param DiagId Diagnostic which should be emitted if error is found.
9785 /// \param NoteId Diagnostic note for the main error message.
9786 /// \return true if statement is not an update expression, false otherwise.
9787 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
9788 /// Return the 'x' lvalue part of the source atomic expression.
9789 Expr *getX() const { return X; }
9790 /// Return the 'expr' rvalue part of the source atomic expression.
9791 Expr *getExpr() const { return E; }
9792 /// Return the update expression used in calculation of the updated
9793 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
9794 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
9795 Expr *getUpdateExpr() const { return UpdateExpr; }
9796 /// Return true if 'x' is LHS in RHS part of full update expression,
9797 /// false otherwise.
9798 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
9799
9800 /// true if the source expression is a postfix unary operation, false
9801 /// if it is a prefix unary operation.
9802 bool isPostfixUpdate() const { return IsPostfixUpdate; }
9803
9804private:
9805 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
9806 unsigned NoteId = 0);
9807};
9808} // namespace
9809
9810bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
9811 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
9812 ExprAnalysisErrorCode ErrorFound = NoError;
9813 SourceLocation ErrorLoc, NoteLoc;
9814 SourceRange ErrorRange, NoteRange;
9815 // Allowed constructs are:
9816 // x = x binop expr;
9817 // x = expr binop x;
9818 if (AtomicBinOp->getOpcode() == BO_Assign) {
9819 X = AtomicBinOp->getLHS();
9820 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
9821 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
9822 if (AtomicInnerBinOp->isMultiplicativeOp() ||
9823 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
9824 AtomicInnerBinOp->isBitwiseOp()) {
9825 Op = AtomicInnerBinOp->getOpcode();
9826 OpLoc = AtomicInnerBinOp->getOperatorLoc();
9827 Expr *LHS = AtomicInnerBinOp->getLHS();
9828 Expr *RHS = AtomicInnerBinOp->getRHS();
9829 llvm::FoldingSetNodeID XId, LHSId, RHSId;
9830 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
9831 /*Canonical=*/true);
9832 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
9833 /*Canonical=*/true);
9834 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
9835 /*Canonical=*/true);
9836 if (XId == LHSId) {
9837 E = RHS;
9838 IsXLHSInRHSPart = true;
9839 } else if (XId == RHSId) {
9840 E = LHS;
9841 IsXLHSInRHSPart = false;
9842 } else {
9843 ErrorLoc = AtomicInnerBinOp->getExprLoc();
9844 ErrorRange = AtomicInnerBinOp->getSourceRange();
9845 NoteLoc = X->getExprLoc();
9846 NoteRange = X->getSourceRange();
9847 ErrorFound = NotAnUpdateExpression;
9848 }
9849 } else {
9850 ErrorLoc = AtomicInnerBinOp->getExprLoc();
9851 ErrorRange = AtomicInnerBinOp->getSourceRange();
9852 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
9853 NoteRange = SourceRange(NoteLoc, NoteLoc);
9854 ErrorFound = NotABinaryOperator;
9855 }
9856 } else {
9857 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
9858 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
9859 ErrorFound = NotABinaryExpression;
9860 }
9861 } else {
9862 ErrorLoc = AtomicBinOp->getExprLoc();
9863 ErrorRange = AtomicBinOp->getSourceRange();
9864 NoteLoc = AtomicBinOp->getOperatorLoc();
9865 NoteRange = SourceRange(NoteLoc, NoteLoc);
9866 ErrorFound = NotAnAssignmentOp;
9867 }
9868 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
9869 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
9870 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
9871 return true;
9872 }
9873 if (SemaRef.CurContext->isDependentContext())
9874 E = X = UpdateExpr = nullptr;
9875 return ErrorFound != NoError;
9876}
9877
9878bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
9879 unsigned NoteId) {
9880 ExprAnalysisErrorCode ErrorFound = NoError;
9881 SourceLocation ErrorLoc, NoteLoc;
9882 SourceRange ErrorRange, NoteRange;
9883 // Allowed constructs are:
9884 // x++;
9885 // x--;
9886 // ++x;
9887 // --x;
9888 // x binop= expr;
9889 // x = x binop expr;
9890 // x = expr binop x;
9891 if (auto *AtomicBody = dyn_cast<Expr>(S)) {
9892 AtomicBody = AtomicBody->IgnoreParenImpCasts();
9893 if (AtomicBody->getType()->isScalarType() ||
9894 AtomicBody->isInstantiationDependent()) {
9895 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
9896 AtomicBody->IgnoreParenImpCasts())) {
9897 // Check for Compound Assignment Operation
9898 Op = BinaryOperator::getOpForCompoundAssignment(
9899 AtomicCompAssignOp->getOpcode());
9900 OpLoc = AtomicCompAssignOp->getOperatorLoc();
9901 E = AtomicCompAssignOp->getRHS();
9902 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
9903 IsXLHSInRHSPart = true;
9904 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
9905 AtomicBody->IgnoreParenImpCasts())) {
9906 // Check for Binary Operation
9907 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
9908 return true;
9909 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
9910 AtomicBody->IgnoreParenImpCasts())) {
9911 // Check for Unary Operation
9912 if (AtomicUnaryOp->isIncrementDecrementOp()) {
9913 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
9914 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
9915 OpLoc = AtomicUnaryOp->getOperatorLoc();
9916 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
9917 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
9918 IsXLHSInRHSPart = true;
9919 } else {
9920 ErrorFound = NotAnUnaryIncDecExpression;
9921 ErrorLoc = AtomicUnaryOp->getExprLoc();
9922 ErrorRange = AtomicUnaryOp->getSourceRange();
9923 NoteLoc = AtomicUnaryOp->getOperatorLoc();
9924 NoteRange = SourceRange(NoteLoc, NoteLoc);
9925 }
9926 } else if (!AtomicBody->isInstantiationDependent()) {
9927 ErrorFound = NotABinaryOrUnaryExpression;
9928 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
9929 NoteRange = ErrorRange = AtomicBody->getSourceRange();
9930 }
9931 } else {
9932 ErrorFound = NotAScalarType;
9933 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
9934 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9935 }
9936 } else {
9937 ErrorFound = NotAnExpression;
9938 NoteLoc = ErrorLoc = S->getBeginLoc();
9939 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9940 }
9941 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
9942 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
9943 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
9944 return true;
9945 }
9946 if (SemaRef.CurContext->isDependentContext())
9947 E = X = UpdateExpr = nullptr;
9948 if (ErrorFound == NoError && E && X) {
9949 // Build an update expression of form 'OpaqueValueExpr(x) binop
9950 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
9951 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
9952 auto *OVEX = new (SemaRef.getASTContext())
9953 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
9954 auto *OVEExpr = new (SemaRef.getASTContext())
9955 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue);
9956 ExprResult Update =
9957 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
9958 IsXLHSInRHSPart ? OVEExpr : OVEX);
9959 if (Update.isInvalid())
9960 return true;
9961 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
9962 Sema::AA_Casting);
9963 if (Update.isInvalid())
9964 return true;
9965 UpdateExpr = Update.get();
9966 }
9967 return ErrorFound != NoError;
9968}
9969
9970StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
9971 Stmt *AStmt,
9972 SourceLocation StartLoc,
9973 SourceLocation EndLoc) {
9974 // Register location of the first atomic directive.
9975 DSAStack->addAtomicDirectiveLoc(StartLoc);
9976 if (!AStmt)
9977 return StmtError();
9978
9979 // 1.2.2 OpenMP Language Terminology
9980 // Structured block - An executable statement with a single entry at the
9981 // top and a single exit at the bottom.
9982 // The point of exit cannot be a branch out of the structured block.
9983 // longjmp() and throw() must not violate the entry/exit criteria.
9984 OpenMPClauseKind AtomicKind = OMPC_unknown;
9985 SourceLocation AtomicKindLoc;
9986 OpenMPClauseKind MemOrderKind = OMPC_unknown;
9987 SourceLocation MemOrderLoc;
9988 for (const OMPClause *C : Clauses) {
9989 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
9990 C->getClauseKind() == OMPC_update ||
9991 C->getClauseKind() == OMPC_capture) {
9992 if (AtomicKind != OMPC_unknown) {
9993 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
9994 << SourceRange(C->getBeginLoc(), C->getEndLoc());
9995 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
9996 << getOpenMPClauseName(AtomicKind);
9997 } else {
9998 AtomicKind = C->getClauseKind();
9999 AtomicKindLoc = C->getBeginLoc();
10000 }
10001 }
10002 if (C->getClauseKind() == OMPC_seq_cst ||
10003 C->getClauseKind() == OMPC_acq_rel ||
10004 C->getClauseKind() == OMPC_acquire ||
10005 C->getClauseKind() == OMPC_release ||
10006 C->getClauseKind() == OMPC_relaxed) {
10007 if (MemOrderKind != OMPC_unknown) {
10008 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
10009 << getOpenMPDirectiveName(OMPD_atomic) << 0
10010 << SourceRange(C->getBeginLoc(), C->getEndLoc());
10011 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10012 << getOpenMPClauseName(MemOrderKind);
10013 } else {
10014 MemOrderKind = C->getClauseKind();
10015 MemOrderLoc = C->getBeginLoc();
10016 }
10017 }
10018 }
10019 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
10020 // If atomic-clause is read then memory-order-clause must not be acq_rel or
10021 // release.
10022 // If atomic-clause is write then memory-order-clause must not be acq_rel or
10023 // acquire.
10024 // If atomic-clause is update or not present then memory-order-clause must not
10025 // be acq_rel or acquire.
10026 if ((AtomicKind == OMPC_read &&
10027 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
10028 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
10029 AtomicKind == OMPC_unknown) &&
10030 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
10031 SourceLocation Loc = AtomicKindLoc;
10032 if (AtomicKind == OMPC_unknown)
10033 Loc = StartLoc;
10034 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
10035 << getOpenMPClauseName(AtomicKind)
10036 << (AtomicKind == OMPC_unknown ? 1 : 0)
10037 << getOpenMPClauseName(MemOrderKind);
10038 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10039 << getOpenMPClauseName(MemOrderKind);
10040 }
10041
10042 Stmt *Body = AStmt;
10043 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
10044 Body = EWC->getSubExpr();
10045
10046 Expr *X = nullptr;
10047 Expr *V = nullptr;
10048 Expr *E = nullptr;
10049 Expr *UE = nullptr;
10050 bool IsXLHSInRHSPart = false;
10051 bool IsPostfixUpdate = false;
10052 // OpenMP [2.12.6, atomic Construct]
10053 // In the next expressions:
10054 // * x and v (as applicable) are both l-value expressions with scalar type.
10055 // * During the execution of an atomic region, multiple syntactic
10056 // occurrences of x must designate the same storage location.
10057 // * Neither of v and expr (as applicable) may access the storage location
10058 // designated by x.
10059 // * Neither of x and expr (as applicable) may access the storage location
10060 // designated by v.
10061 // * expr is an expression with scalar type.
10062 // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
10063 // * binop, binop=, ++, and -- are not overloaded operators.
10064 // * The expression x binop expr must be numerically equivalent to x binop
10065 // (expr). This requirement is satisfied if the operators in expr have
10066 // precedence greater than binop, or by using parentheses around expr or
10067 // subexpressions of expr.
10068 // * The expression expr binop x must be numerically equivalent to (expr)
10069 // binop x. This requirement is satisfied if the operators in expr have
10070 // precedence equal to or greater than binop, or by using parentheses around
10071 // expr or subexpressions of expr.
10072 // * For forms that allow multiple occurrences of x, the number of times
10073 // that x is evaluated is unspecified.
10074 if (AtomicKind == OMPC_read) {
10075 enum {
10076 NotAnExpression,
10077 NotAnAssignmentOp,
10078 NotAScalarType,
10079 NotAnLValue,
10080 NoError
10081 } ErrorFound = NoError;
10082 SourceLocation ErrorLoc, NoteLoc;
10083 SourceRange ErrorRange, NoteRange;
10084 // If clause is read:
10085 // v = x;
10086 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10087 const auto *AtomicBinOp =
10088 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10089 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10090 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
10091 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
10092 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
10093 (V->isInstantiationDependent() || V->getType()->isScalarType())) {
10094 if (!X->isLValue() || !V->isLValue()) {
10095 const Expr *NotLValueExpr = X->isLValue() ? V : X;
10096 ErrorFound = NotAnLValue;
10097 ErrorLoc = AtomicBinOp->getExprLoc();
10098 ErrorRange = AtomicBinOp->getSourceRange();
10099 NoteLoc = NotLValueExpr->getExprLoc();
10100 NoteRange = NotLValueExpr->getSourceRange();
10101 }
10102 } else if (!X->isInstantiationDependent() ||
10103 !V->isInstantiationDependent()) {
10104 const Expr *NotScalarExpr =
10105 (X->isInstantiationDependent() || X->getType()->isScalarType())
10106 ? V
10107 : X;
10108 ErrorFound = NotAScalarType;
10109 ErrorLoc = AtomicBinOp->getExprLoc();
10110 ErrorRange = AtomicBinOp->getSourceRange();
10111 NoteLoc = NotScalarExpr->getExprLoc();
10112 NoteRange = NotScalarExpr->getSourceRange();
10113 }
10114 } else if (!AtomicBody->isInstantiationDependent()) {
10115 ErrorFound = NotAnAssignmentOp;
10116 ErrorLoc = AtomicBody->getExprLoc();
10117 ErrorRange = AtomicBody->getSourceRange();
10118 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10119 : AtomicBody->getExprLoc();
10120 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10121 : AtomicBody->getSourceRange();
10122 }
10123 } else {
10124 ErrorFound = NotAnExpression;
10125 NoteLoc = ErrorLoc = Body->getBeginLoc();
10126 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10127 }
10128 if (ErrorFound != NoError) {
10129 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
10130 << ErrorRange;
10131 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
10132 << NoteRange;
10133 return StmtError();
10134 }
10135 if (CurContext->isDependentContext())
10136 V = X = nullptr;
10137 } else if (AtomicKind == OMPC_write) {
10138 enum {
10139 NotAnExpression,
10140 NotAnAssignmentOp,
10141 NotAScalarType,
10142 NotAnLValue,
10143 NoError
10144 } ErrorFound = NoError;
10145 SourceLocation ErrorLoc, NoteLoc;
10146 SourceRange ErrorRange, NoteRange;
10147 // If clause is write:
10148 // x = expr;
10149 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10150 const auto *AtomicBinOp =
10151 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10152 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10153 X = AtomicBinOp->getLHS();
10154 E = AtomicBinOp->getRHS();
10155 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
10156 (E->isInstantiationDependent() || E->getType()->isScalarType())) {
10157 if (!X->isLValue()) {
10158 ErrorFound = NotAnLValue;
10159 ErrorLoc = AtomicBinOp->getExprLoc();
10160 ErrorRange = AtomicBinOp->getSourceRange();
10161 NoteLoc = X->getExprLoc();
10162 NoteRange = X->getSourceRange();
10163 }
10164 } else if (!X->isInstantiationDependent() ||
10165 !E->isInstantiationDependent()) {
10166 const Expr *NotScalarExpr =
10167 (X->isInstantiationDependent() || X->getType()->isScalarType())
10168 ? E
10169 : X;
10170 ErrorFound = NotAScalarType;
10171 ErrorLoc = AtomicBinOp->getExprLoc();
10172 ErrorRange = AtomicBinOp->getSourceRange();
10173 NoteLoc = NotScalarExpr->getExprLoc();
10174 NoteRange = NotScalarExpr->getSourceRange();
10175 }
10176 } else if (!AtomicBody->isInstantiationDependent()) {
10177 ErrorFound = NotAnAssignmentOp;
10178 ErrorLoc = AtomicBody->getExprLoc();
10179 ErrorRange = AtomicBody->getSourceRange();
10180 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10181 : AtomicBody->getExprLoc();
10182 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10183 : AtomicBody->getSourceRange();
10184 }
10185 } else {
10186 ErrorFound = NotAnExpression;
10187 NoteLoc = ErrorLoc = Body->getBeginLoc();
10188 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10189 }
10190 if (ErrorFound != NoError) {
10191 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
10192 << ErrorRange;
10193 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
10194 << NoteRange;
10195 return StmtError();
10196 }
10197 if (CurContext->isDependentContext())
10198 E = X = nullptr;
10199 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
10200 // If clause is update:
10201 // x++;
10202 // x--;
10203 // ++x;
10204 // --x;
10205 // x binop= expr;
10206 // x = x binop expr;
10207 // x = expr binop x;
10208 OpenMPAtomicUpdateChecker Checker(*this);
10209 if (Checker.checkStatement(
10210 Body, (AtomicKind == OMPC_update)
10211 ? diag::err_omp_atomic_update_not_expression_statement
10212 : diag::err_omp_atomic_not_expression_statement,
10213 diag::note_omp_atomic_update))
10214 return StmtError();
10215 if (!CurContext->isDependentContext()) {
10216 E = Checker.getExpr();
10217 X = Checker.getX();
10218 UE = Checker.getUpdateExpr();
10219 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10220 }
10221 } else if (AtomicKind == OMPC_capture) {
10222 enum {
10223 NotAnAssignmentOp,
10224 NotACompoundStatement,
10225 NotTwoSubstatements,
10226 NotASpecificExpression,
10227 NoError
10228 } ErrorFound = NoError;
10229 SourceLocation ErrorLoc, NoteLoc;
10230 SourceRange ErrorRange, NoteRange;
10231 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10232 // If clause is a capture:
10233 // v = x++;
10234 // v = x--;
10235 // v = ++x;
10236 // v = --x;
10237 // v = x binop= expr;
10238 // v = x = x binop expr;
10239 // v = x = expr binop x;
10240 const auto *AtomicBinOp =
10241 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10242 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10243 V = AtomicBinOp->getLHS();
10244 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
10245 OpenMPAtomicUpdateChecker Checker(*this);
10246 if (Checker.checkStatement(
10247 Body, diag::err_omp_atomic_capture_not_expression_statement,
10248 diag::note_omp_atomic_update))
10249 return StmtError();
10250 E = Checker.getExpr();
10251 X = Checker.getX();
10252 UE = Checker.getUpdateExpr();
10253 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10254 IsPostfixUpdate = Checker.isPostfixUpdate();
10255 } else if (!AtomicBody->isInstantiationDependent()) {
10256 ErrorLoc = AtomicBody->getExprLoc();
10257 ErrorRange = AtomicBody->getSourceRange();
10258 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10259 : AtomicBody->getExprLoc();
10260 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10261 : AtomicBody->getSourceRange();
10262 ErrorFound = NotAnAssignmentOp;
10263 }
10264 if (ErrorFound != NoError) {
10265 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
10266 << ErrorRange;
10267 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
10268 return StmtError();
10269 }
10270 if (CurContext->isDependentContext())
10271 UE = V = E = X = nullptr;
10272 } else {
10273 // If clause is a capture:
10274 // { v = x; x = expr; }
10275 // { v = x; x++; }
10276 // { v = x; x--; }
10277 // { v = x; ++x; }
10278 // { v = x; --x; }
10279 // { v = x; x binop= expr; }
10280 // { v = x; x = x binop expr; }
10281 // { v = x; x = expr binop x; }
10282 // { x++; v = x; }
10283 // { x--; v = x; }
10284 // { ++x; v = x; }
10285 // { --x; v = x; }
10286 // { x binop= expr; v = x; }
10287 // { x = x binop expr; v = x; }
10288 // { x = expr binop x; v = x; }
10289 if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
10290 // Check that this is { expr1; expr2; }
10291 if (CS->size() == 2) {
10292 Stmt *First = CS->body_front();
10293 Stmt *Second = CS->body_back();
10294 if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
10295 First = EWC->getSubExpr()->IgnoreParenImpCasts();
10296 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
10297 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
10298 // Need to find what subexpression is 'v' and what is 'x'.
10299 OpenMPAtomicUpdateChecker Checker(*this);
10300 bool IsUpdateExprFound = !Checker.checkStatement(Second);
10301 BinaryOperator *BinOp = nullptr;
10302 if (IsUpdateExprFound) {
10303 BinOp = dyn_cast<BinaryOperator>(First);
10304 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10305 }
10306 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10307 // { v = x; x++; }
10308 // { v = x; x--; }
10309 // { v = x; ++x; }
10310 // { v = x; --x; }
10311 // { v = x; x binop= expr; }
10312 // { v = x; x = x binop expr; }
10313 // { v = x; x = expr binop x; }
10314 // Check that the first expression has form v = x.
10315 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10316 llvm::FoldingSetNodeID XId, PossibleXId;
10317 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10318 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10319 IsUpdateExprFound = XId == PossibleXId;
10320 if (IsUpdateExprFound) {
10321 V = BinOp->getLHS();
10322 X = Checker.getX();
10323 E = Checker.getExpr();
10324 UE = Checker.getUpdateExpr();
10325 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10326 IsPostfixUpdate = true;
10327 }
10328 }
10329 if (!IsUpdateExprFound) {
10330 IsUpdateExprFound = !Checker.checkStatement(First);
10331 BinOp = nullptr;
10332 if (IsUpdateExprFound) {
10333 BinOp = dyn_cast<BinaryOperator>(Second);
10334 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10335 }
10336 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10337 // { x++; v = x; }
10338 // { x--; v = x; }
10339 // { ++x; v = x; }
10340 // { --x; v = x; }
10341 // { x binop= expr; v = x; }
10342 // { x = x binop expr; v = x; }
10343 // { x = expr binop x; v = x; }
10344 // Check that the second expression has form v = x.
10345 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10346 llvm::FoldingSetNodeID XId, PossibleXId;
10347 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10348 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10349 IsUpdateExprFound = XId == PossibleXId;
10350 if (IsUpdateExprFound) {
10351 V = BinOp->getLHS();
10352 X = Checker.getX();
10353 E = Checker.getExpr();
10354 UE = Checker.getUpdateExpr();
10355 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10356 IsPostfixUpdate = false;
10357 }
10358 }
10359 }
10360 if (!IsUpdateExprFound) {
10361 // { v = x; x = expr; }
10362 auto *FirstExpr = dyn_cast<Expr>(First);
10363 auto *SecondExpr = dyn_cast<Expr>(Second);
10364 if (!FirstExpr || !SecondExpr ||
10365 !(FirstExpr->isInstantiationDependent() ||
10366 SecondExpr->isInstantiationDependent())) {
10367 auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
10368 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
10369 ErrorFound = NotAnAssignmentOp;
10370 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
10371 : First->getBeginLoc();
10372 NoteRange = ErrorRange = FirstBinOp
10373 ? FirstBinOp->getSourceRange()
10374 : SourceRange(ErrorLoc, ErrorLoc);
10375 } else {
10376 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
10377 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
10378 ErrorFound = NotAnAssignmentOp;
10379 NoteLoc = ErrorLoc = SecondBinOp
10380 ? SecondBinOp->getOperatorLoc()
10381 : Second->getBeginLoc();
10382 NoteRange = ErrorRange =
10383 SecondBinOp ? SecondBinOp->getSourceRange()
10384 : SourceRange(ErrorLoc, ErrorLoc);
10385 } else {
10386 Expr *PossibleXRHSInFirst =
10387 FirstBinOp->getRHS()->IgnoreParenImpCasts();
10388 Expr *PossibleXLHSInSecond =
10389 SecondBinOp->getLHS()->IgnoreParenImpCasts();
10390 llvm::FoldingSetNodeID X1Id, X2Id;
10391 PossibleXRHSInFirst->Profile(X1Id, Context,
10392 /*Canonical=*/true);
10393 PossibleXLHSInSecond->Profile(X2Id, Context,
10394 /*Canonical=*/true);
10395 IsUpdateExprFound = X1Id == X2Id;
10396 if (IsUpdateExprFound) {
10397 V = FirstBinOp->getLHS();
10398 X = SecondBinOp->getLHS();
10399 E = SecondBinOp->getRHS();
10400 UE = nullptr;
10401 IsXLHSInRHSPart = false;
10402 IsPostfixUpdate = true;
10403 } else {
10404 ErrorFound = NotASpecificExpression;
10405 ErrorLoc = FirstBinOp->getExprLoc();
10406 ErrorRange = FirstBinOp->getSourceRange();
10407 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
10408 NoteRange = SecondBinOp->getRHS()->getSourceRange();
10409 }
10410 }
10411 }
10412 }
10413 }
10414 } else {
10415 NoteLoc = ErrorLoc = Body->getBeginLoc();
10416 NoteRange = ErrorRange =
10417 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
10418 ErrorFound = NotTwoSubstatements;
10419 }
10420 } else {
10421 NoteLoc = ErrorLoc = Body->getBeginLoc();
10422 NoteRange = ErrorRange =
10423 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
10424 ErrorFound = NotACompoundStatement;
10425 }
10426 if (ErrorFound != NoError) {
10427 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
10428 << ErrorRange;
10429 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
10430 return StmtError();
10431 }
10432 if (CurContext->isDependentContext())
10433 UE = V = E = X = nullptr;
10434 }
10435 }
10436
10437 setFunctionHasBranchProtectedScope();
10438
10439 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10440 X, V, E, UE, IsXLHSInRHSPart,
10441 IsPostfixUpdate);
10442}
10443
10444StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
10445 Stmt *AStmt,
10446 SourceLocation StartLoc,
10447 SourceLocation EndLoc) {
10448 if (!AStmt)
10449 return StmtError();
10450
10451 auto *CS = cast<CapturedStmt>(AStmt);
10452 // 1.2.2 OpenMP Language Terminology
10453 // Structured block - An executable statement with a single entry at the
10454 // top and a single exit at the bottom.
10455 // The point of exit cannot be a branch out of the structured block.
10456 // longjmp() and throw() must not violate the entry/exit criteria.
10457 CS->getCapturedDecl()->setNothrow();
10458 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
10459 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10460 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10461 // 1.2.2 OpenMP Language Terminology
10462 // Structured block - An executable statement with a single entry at the
10463 // top and a single exit at the bottom.
10464 // The point of exit cannot be a branch out of the structured block.
10465 // longjmp() and throw() must not violate the entry/exit criteria.
10466 CS->getCapturedDecl()->setNothrow();
10467 }
10468
10469 // OpenMP [2.16, Nesting of Regions]
10470 // If specified, a teams construct must be contained within a target
10471 // construct. That target construct must contain no statements or directives
10472 // outside of the teams construct.
10473 if (DSAStack->hasInnerTeamsRegion()) {
10474 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
10475 bool OMPTeamsFound = true;
10476 if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
10477 auto I = CS->body_begin();
10478 while (I != CS->body_end()) {
10479 const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
10480 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
10481 OMPTeamsFound) {
10482
10483 OMPTeamsFound = false;
10484 break;
10485 }
10486 ++I;
10487 }
10488 assert(I != CS->body_end() && "Not found statement");
10489 S = *I;
10490 } else {
10491 const auto *OED = dyn_cast<OMPExecutableDirective>(S);
10492 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
10493 }
10494 if (!OMPTeamsFound) {
10495 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
10496 Diag(DSAStack->getInnerTeamsRegionLoc(),
10497 diag::note_omp_nested_teams_construct_here);
10498 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
10499 << isa<OMPExecutableDirective>(S);
10500 return StmtError();
10501 }
10502 }
10503
10504 setFunctionHasBranchProtectedScope();
10505
10506 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10507}
10508
10509StmtResult
10510Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
10511 Stmt *AStmt, SourceLocation StartLoc,
10512 SourceLocation EndLoc) {
10513 if (!AStmt)
10514 return StmtError();
10515
10516 auto *CS = cast<CapturedStmt>(AStmt);
10517 // 1.2.2 OpenMP Language Terminology
10518 // Structured block - An executable statement with a single entry at the
10519 // top and a single exit at the bottom.
10520 // The point of exit cannot be a branch out of the structured block.
10521 // longjmp() and throw() must not violate the entry/exit criteria.
10522 CS->getCapturedDecl()->setNothrow();
10523 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
10524 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10525 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10526 // 1.2.2 OpenMP Language Terminology
10527 // Structured block - An executable statement with a single entry at the
10528 // top and a single exit at the bottom.
10529 // The point of exit cannot be a branch out of the structured block.
10530 // longjmp() and throw() must not violate the entry/exit criteria.
10531 CS->getCapturedDecl()->setNothrow();
10532 }
10533
10534 setFunctionHasBranchProtectedScope();
10535
10536 return OMPTargetParallelDirective::Create(
10537 Context, StartLoc, EndLoc, Clauses, AStmt,
10538 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10539}
10540
10541StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
10542 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10543 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10544 if (!AStmt)
10545 return StmtError();
10546
10547 auto *CS = cast<CapturedStmt>(AStmt);
10548 // 1.2.2 OpenMP Language Terminology
10549 // Structured block - An executable statement with a single entry at the
10550 // top and a single exit at the bottom.
10551 // The point of exit cannot be a branch out of the structured block.
10552 // longjmp() and throw() must not violate the entry/exit criteria.
10553 CS->getCapturedDecl()->setNothrow();
10554 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
10555 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10556 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10557 // 1.2.2 OpenMP Language Terminology
10558 // Structured block - An executable statement with a single entry at the
10559 // top and a single exit at the bottom.
10560 // The point of exit cannot be a branch out of the structured block.
10561 // longjmp() and throw() must not violate the entry/exit criteria.
10562 CS->getCapturedDecl()->setNothrow();
10563 }
10564
10565 OMPLoopDirective::HelperExprs B;
10566 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10567 // define the nested loops number.
10568 unsigned NestedLoopCount =
10569 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
10570 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
10571 VarsWithImplicitDSA, B);
10572 if (NestedLoopCount == 0)
10573 return StmtError();
10574
10575 assert((CurContext->isDependentContext() || B.builtAll()) &&
10576 "omp target parallel for loop exprs were not built");
10577
10578 if (!CurContext->isDependentContext()) {
10579 // Finalize the clauses that need pre-built expressions for CodeGen.
10580 for (OMPClause *C : Clauses) {
10581 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10582 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10583 B.NumIterations, *this, CurScope,
10584 DSAStack))
10585 return StmtError();
10586 }
10587 }
10588
10589 setFunctionHasBranchProtectedScope();
10590 return OMPTargetParallelForDirective::Create(
10591 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10592 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10593}
10594
10595/// Check for existence of a map clause in the list of clauses.
10596static bool hasClauses(ArrayRef<OMPClause *> Clauses,
10597 const OpenMPClauseKind K) {
10598 return llvm::any_of(
10599 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
10600}
10601
10602template <typename... Params>
10603static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
10604 const Params... ClauseTypes) {
10605 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
10606}
10607
10608StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
10609 Stmt *AStmt,
10610 SourceLocation StartLoc,
10611 SourceLocation EndLoc) {
10612 if (!AStmt)
10613 return StmtError();
10614
10615 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10616
10617 // OpenMP [2.12.2, target data Construct, Restrictions]
10618 // At least one map, use_device_addr or use_device_ptr clause must appear on
10619 // the directive.
10620 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
10621 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
10622 StringRef Expected;
10623 if (LangOpts.OpenMP < 50)
10624 Expected = "'map' or 'use_device_ptr'";
10625 else
10626 Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
10627 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10628 << Expected << getOpenMPDirectiveName(OMPD_target_data);
10629 return StmtError();
10630 }
10631
10632 setFunctionHasBranchProtectedScope();
10633
10634 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10635 AStmt);
10636}
10637
10638StmtResult
10639Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
10640 SourceLocation StartLoc,
10641 SourceLocation EndLoc, Stmt *AStmt) {
10642 if (!AStmt)
10643 return StmtError();
10644
10645 auto *CS = cast<CapturedStmt>(AStmt);
10646 // 1.2.2 OpenMP Language Terminology
10647 // Structured block - An executable statement with a single entry at the
10648 // top and a single exit at the bottom.
10649 // The point of exit cannot be a branch out of the structured block.
10650 // longjmp() and throw() must not violate the entry/exit criteria.
10651 CS->getCapturedDecl()->setNothrow();
10652 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
10653 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10654 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10655 // 1.2.2 OpenMP Language Terminology
10656 // Structured block - An executable statement with a single entry at the
10657 // top and a single exit at the bottom.
10658 // The point of exit cannot be a branch out of the structured block.
10659 // longjmp() and throw() must not violate the entry/exit criteria.
10660 CS->getCapturedDecl()->setNothrow();
10661 }
10662
10663 // OpenMP [2.10.2, Restrictions, p. 99]
10664 // At least one map clause must appear on the directive.
10665 if (!hasClauses(Clauses, OMPC_map)) {
10666 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10667 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
10668 return StmtError();
10669 }
10670
10671 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10672 AStmt);
10673}
10674
10675StmtResult
10676Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
10677 SourceLocation StartLoc,
10678 SourceLocation EndLoc, Stmt *AStmt) {
10679 if (!AStmt)
10680 return StmtError();
10681
10682 auto *CS = cast<CapturedStmt>(AStmt);
10683 // 1.2.2 OpenMP Language Terminology
10684 // Structured block - An executable statement with a single entry at the
10685 // top and a single exit at the bottom.
10686 // The point of exit cannot be a branch out of the structured block.
10687 // longjmp() and throw() must not violate the entry/exit criteria.
10688 CS->getCapturedDecl()->setNothrow();
10689 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
10690 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10691 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10692 // 1.2.2 OpenMP Language Terminology
10693 // Structured block - An executable statement with a single entry at the
10694 // top and a single exit at the bottom.
10695 // The point of exit cannot be a branch out of the structured block.
10696 // longjmp() and throw() must not violate the entry/exit criteria.
10697 CS->getCapturedDecl()->setNothrow();
10698 }
10699
10700 // OpenMP [2.10.3, Restrictions, p. 102]
10701 // At least one map clause must appear on the directive.
10702 if (!hasClauses(Clauses, OMPC_map)) {
10703 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10704 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
10705 return StmtError();
10706 }
10707
10708 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10709 AStmt);
10710}
10711
10712StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
10713 SourceLocation StartLoc,
10714 SourceLocation EndLoc,
10715 Stmt *AStmt) {
10716 if (!AStmt)
10717 return StmtError();
10718
10719 auto *CS = cast<CapturedStmt>(AStmt);
10720 // 1.2.2 OpenMP Language Terminology
10721 // Structured block - An executable statement with a single entry at the
10722 // top and a single exit at the bottom.
10723 // The point of exit cannot be a branch out of the structured block.
10724 // longjmp() and throw() must not violate the entry/exit criteria.
10725 CS->getCapturedDecl()->setNothrow();
10726 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
10727 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10728 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10729 // 1.2.2 OpenMP Language Terminology
10730 // Structured block - An executable statement with a single entry at the
10731 // top and a single exit at the bottom.
10732 // The point of exit cannot be a branch out of the structured block.
10733 // longjmp() and throw() must not violate the entry/exit criteria.
10734 CS->getCapturedDecl()->setNothrow();
10735 }
10736
10737 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
10738 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
10739 return StmtError();
10740 }
10741 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
10742 AStmt);
10743}
10744
10745StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
10746 Stmt *AStmt, SourceLocation StartLoc,
10747 SourceLocation EndLoc) {
10748 if (!AStmt)
10749 return StmtError();
10750
10751 auto *CS = cast<CapturedStmt>(AStmt);
10752 // 1.2.2 OpenMP Language Terminology
10753 // Structured block - An executable statement with a single entry at the
10754 // top and a single exit at the bottom.
10755 // The point of exit cannot be a branch out of the structured block.
10756 // longjmp() and throw() must not violate the entry/exit criteria.
10757 CS->getCapturedDecl()->setNothrow();
10758
10759 setFunctionHasBranchProtectedScope();
10760
10761 DSAStack->setParentTeamsRegionLoc(StartLoc);
10762
10763 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10764}
10765
10766StmtResult
10767Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
10768 SourceLocation EndLoc,
10769 OpenMPDirectiveKind CancelRegion) {
10770 if (DSAStack->isParentNowaitRegion()) {
10771 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
10772 return StmtError();
10773 }
10774 if (DSAStack->isParentOrderedRegion()) {
10775 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
10776 return StmtError();
10777 }
10778 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
10779 CancelRegion);
10780}
10781
10782StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
10783 SourceLocation StartLoc,
10784 SourceLocation EndLoc,
10785 OpenMPDirectiveKind CancelRegion) {
10786 if (DSAStack->isParentNowaitRegion()) {
10787 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
10788 return StmtError();
10789 }
10790 if (DSAStack->isParentOrderedRegion()) {
10791 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
10792 return StmtError();
10793 }
10794 DSAStack->setParentCancelRegion(/*Cancel=*/true);
10795 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
10796 CancelRegion);
10797}
10798
10799static bool checkGrainsizeNumTasksClauses(Sema &S,
10800 ArrayRef<OMPClause *> Clauses) {
10801 const OMPClause *PrevClause = nullptr;
10802 bool ErrorFound = false;
10803 for (const OMPClause *C : Clauses) {
10804 if (C->getClauseKind() == OMPC_grainsize ||
10805 C->getClauseKind() == OMPC_num_tasks) {
10806 if (!PrevClause)
10807 PrevClause = C;
10808 else if (PrevClause->getClauseKind() != C->getClauseKind()) {
10809 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
10810 << getOpenMPClauseName(C->getClauseKind())
10811 << getOpenMPClauseName(PrevClause->getClauseKind());
10812 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
10813 << getOpenMPClauseName(PrevClause->getClauseKind());
10814 ErrorFound = true;
10815 }
10816 }
10817 }
10818 return ErrorFound;
10819}
10820
10821static bool checkReductionClauseWithNogroup(Sema &S,
10822 ArrayRef<OMPClause *> Clauses) {
10823 const OMPClause *ReductionClause = nullptr;
10824 const OMPClause *NogroupClause = nullptr;
10825 for (const OMPClause *C : Clauses) {
10826 if (C->getClauseKind() == OMPC_reduction) {
10827 ReductionClause = C;
10828 if (NogroupClause)
10829 break;
10830 continue;
10831 }
10832 if (C->getClauseKind() == OMPC_nogroup) {
10833 NogroupClause = C;
10834 if (ReductionClause)
10835 break;
10836 continue;
10837 }
10838 }
10839 if (ReductionClause && NogroupClause) {
10840 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
10841 << SourceRange(NogroupClause->getBeginLoc(),
10842 NogroupClause->getEndLoc());
10843 return true;
10844 }
10845 return false;
10846}
10847
10848StmtResult Sema::ActOnOpenMPTaskLoopDirective(
10849 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10850 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10851 if (!AStmt)
10852 return StmtError();
10853
10854 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10855 OMPLoopDirective::HelperExprs B;
10856 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10857 // define the nested loops number.
10858 unsigned NestedLoopCount =
10859 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
10860 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
10861 VarsWithImplicitDSA, B);
10862 if (NestedLoopCount == 0)
10863 return StmtError();
10864
10865 assert((CurContext->isDependentContext() || B.builtAll()) &&
10866 "omp for loop exprs were not built");
10867
10868 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10869 // The grainsize clause and num_tasks clause are mutually exclusive and may
10870 // not appear on the same taskloop directive.
10871 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10872 return StmtError();
10873 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10874 // If a reduction clause is present on the taskloop directive, the nogroup
10875 // clause must not be specified.
10876 if (checkReductionClauseWithNogroup(*this, Clauses))
10877 return StmtError();
10878
10879 setFunctionHasBranchProtectedScope();
10880 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
10881 NestedLoopCount, Clauses, AStmt, B,
10882 DSAStack->isCancelRegion());
10883}
10884
10885StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
10886 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10887 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10888 if (!AStmt)
10889 return StmtError();
10890
10891 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10892 OMPLoopDirective::HelperExprs B;
10893 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10894 // define the nested loops number.
10895 unsigned NestedLoopCount =
10896 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
10897 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
10898 VarsWithImplicitDSA, B);
10899 if (NestedLoopCount == 0)
10900 return StmtError();
10901
10902 assert((CurContext->isDependentContext() || B.builtAll()) &&
10903 "omp for loop exprs were not built");
10904
10905 if (!CurContext->isDependentContext()) {
10906 // Finalize the clauses that need pre-built expressions for CodeGen.
10907 for (OMPClause *C : Clauses) {
10908 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10909 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10910 B.NumIterations, *this, CurScope,
10911 DSAStack))
10912 return StmtError();
10913 }
10914 }
10915
10916 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10917 // The grainsize clause and num_tasks clause are mutually exclusive and may
10918 // not appear on the same taskloop directive.
10919 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10920 return StmtError();
10921 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10922 // If a reduction clause is present on the taskloop directive, the nogroup
10923 // clause must not be specified.
10924 if (checkReductionClauseWithNogroup(*this, Clauses))
10925 return StmtError();
10926 if (checkSimdlenSafelenSpecified(*this, Clauses))
10927 return StmtError();
10928
10929 setFunctionHasBranchProtectedScope();
10930 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
10931 NestedLoopCount, Clauses, AStmt, B);
10932}
10933
10934StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
10935 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10936 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10937 if (!AStmt)
10938 return StmtError();
10939
10940 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10941 OMPLoopDirective::HelperExprs B;
10942 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10943 // define the nested loops number.
10944 unsigned NestedLoopCount =
10945 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
10946 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
10947 VarsWithImplicitDSA, B);
10948 if (NestedLoopCount == 0)
10949 return StmtError();
10950
10951 assert((CurContext->isDependentContext() || B.builtAll()) &&
10952 "omp for loop exprs were not built");
10953
10954 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10955 // The grainsize clause and num_tasks clause are mutually exclusive and may
10956 // not appear on the same taskloop directive.
10957 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10958 return StmtError();
10959 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10960 // If a reduction clause is present on the taskloop directive, the nogroup
10961 // clause must not be specified.
10962 if (checkReductionClauseWithNogroup(*this, Clauses))
10963 return StmtError();
10964
10965 setFunctionHasBranchProtectedScope();
10966 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
10967 NestedLoopCount, Clauses, AStmt, B,
10968 DSAStack->isCancelRegion());
10969}
10970
10971StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
10972 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10973 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10974 if (!AStmt)
10975 return StmtError();
10976
10977 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10978 OMPLoopDirective::HelperExprs B;
10979 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10980 // define the nested loops number.
10981 unsigned NestedLoopCount =
10982 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
10983 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
10984 VarsWithImplicitDSA, B);
10985 if (NestedLoopCount == 0)
10986 return StmtError();
10987
10988 assert((CurContext->isDependentContext() || B.builtAll()) &&
10989 "omp for loop exprs were not built");
10990
10991 if (!CurContext->isDependentContext()) {
10992 // Finalize the clauses that need pre-built expressions for CodeGen.
10993 for (OMPClause *C : Clauses) {
10994 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10995 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10996 B.NumIterations, *this, CurScope,
10997 DSAStack))
10998 return StmtError();
10999 }
11000 }
11001
11002 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11003 // The grainsize clause and num_tasks clause are mutually exclusive and may
11004 // not appear on the same taskloop directive.
11005 if (checkGrainsizeNumTasksClauses(*this, Clauses))
11006 return StmtError();
11007 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11008 // If a reduction clause is present on the taskloop directive, the nogroup
11009 // clause must not be specified.
11010 if (checkReductionClauseWithNogroup(*this, Clauses))
11011 return StmtError();
11012 if (checkSimdlenSafelenSpecified(*this, Clauses))
11013 return StmtError();
11014
11015 setFunctionHasBranchProtectedScope();
11016 return OMPMasterTaskLoopSimdDirective::Create(
11017 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11018}
11019
11020StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
11021 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11022 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11023 if (!AStmt)
11024 return StmtError();
11025
11026 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11027 auto *CS = cast<CapturedStmt>(AStmt);
11028 // 1.2.2 OpenMP Language Terminology
11029 // Structured block - An executable statement with a single entry at the
11030 // top and a single exit at the bottom.
11031 // The point of exit cannot be a branch out of the structured block.
11032 // longjmp() and throw() must not violate the entry/exit criteria.
11033 CS->getCapturedDecl()->setNothrow();
11034 for (int ThisCaptureLevel =
11035 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
11036 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11037 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11038 // 1.2.2 OpenMP Language Terminology
11039 // Structured block - An executable statement with a single entry at the
11040 // top and a single exit at the bottom.
11041 // The point of exit cannot be a branch out of the structured block.
11042 // longjmp() and throw() must not violate the entry/exit criteria.
11043 CS->getCapturedDecl()->setNothrow();
11044 }
11045
11046 OMPLoopDirective::HelperExprs B;
11047 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11048 // define the nested loops number.
11049 unsigned NestedLoopCount = checkOpenMPLoop(
11050 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
11051 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
11052 VarsWithImplicitDSA, B);
11053 if (NestedLoopCount == 0)
11054 return StmtError();
11055
11056 assert((CurContext->isDependentContext() || B.builtAll()) &&
11057 "omp for loop exprs were not built");
11058
11059 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11060 // The grainsize clause and num_tasks clause are mutually exclusive and may
11061 // not appear on the same taskloop directive.
11062 if (checkGrainsizeNumTasksClauses(*this, Clauses))
11063 return StmtError();
11064 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11065 // If a reduction clause is present on the taskloop directive, the nogroup
11066 // clause must not be specified.
11067 if (checkReductionClauseWithNogroup(*this, Clauses))
11068 return StmtError();
11069
11070 setFunctionHasBranchProtectedScope();
11071 return OMPParallelMasterTaskLoopDirective::Create(
11072 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11073 DSAStack->isCancelRegion());
11074}
11075
11076StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
11077 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11078 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11079 if (!AStmt)
11080 return StmtError();
11081
11082 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11083 auto *CS = cast<CapturedStmt>(AStmt);
11084 // 1.2.2 OpenMP Language Terminology
11085 // Structured block - An executable statement with a single entry at the
11086 // top and a single exit at the bottom.
11087 // The point of exit cannot be a branch out of the structured block.
11088 // longjmp() and throw() must not violate the entry/exit criteria.
11089 CS->getCapturedDecl()->setNothrow();
11090 for (int ThisCaptureLevel =
11091 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
11092 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11093 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11094 // 1.2.2 OpenMP Language Terminology
11095 // Structured block - An executable statement with a single entry at the
11096 // top and a single exit at the bottom.
11097 // The point of exit cannot be a branch out of the structured block.
11098 // longjmp() and throw() must not violate the entry/exit criteria.
11099 CS->getCapturedDecl()->setNothrow();
11100 }
11101
11102 OMPLoopDirective::HelperExprs B;
11103 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11104 // define the nested loops number.
11105 unsigned NestedLoopCount = checkOpenMPLoop(
11106 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
11107 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
11108 VarsWithImplicitDSA, B);
11109 if (NestedLoopCount == 0)
11110 return StmtError();
11111
11112 assert((CurContext->isDependentContext() || B.builtAll()) &&
11113 "omp for loop exprs were not built");
11114
11115 if (!CurContext->isDependentContext()) {
11116 // Finalize the clauses that need pre-built expressions for CodeGen.
11117 for (OMPClause *C : Clauses) {
11118 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11119 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11120 B.NumIterations, *this, CurScope,
11121 DSAStack))
11122 return StmtError();
11123 }
11124 }
11125
11126 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11127 // The grainsize clause and num_tasks clause are mutually exclusive and may
11128 // not appear on the same taskloop directive.
11129 if (checkGrainsizeNumTasksClauses(*this, Clauses))
11130 return StmtError();
11131 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11132 // If a reduction clause is present on the taskloop directive, the nogroup
11133 // clause must not be specified.
11134 if (checkReductionClauseWithNogroup(*this, Clauses))
11135 return StmtError();
11136 if (checkSimdlenSafelenSpecified(*this, Clauses))
11137 return StmtError();
11138
11139 setFunctionHasBranchProtectedScope();
11140 return OMPParallelMasterTaskLoopSimdDirective::Create(
11141 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11142}
11143
11144StmtResult Sema::ActOnOpenMPDistributeDirective(
11145 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11146 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11147 if (!AStmt)
11148 return StmtError();
11149
11150 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11151 OMPLoopDirective::HelperExprs B;
11152 // In presence of clause 'collapse' with number of loops, it will
11153 // define the nested loops number.
11154 unsigned NestedLoopCount =
11155 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
11156 nullptr /*ordered not a clause on distribute*/, AStmt,
11157 *this, *DSAStack, VarsWithImplicitDSA, B);
11158 if (NestedLoopCount == 0)
11159 return StmtError();
11160
11161 assert((CurContext->isDependentContext() || B.builtAll()) &&
11162 "omp for loop exprs were not built");
11163
11164 setFunctionHasBranchProtectedScope();
11165 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
11166 NestedLoopCount, Clauses, AStmt, B);
11167}
11168
11169StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
11170 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11171 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11172 if (!AStmt)
11173 return StmtError();
11174
11175 auto *CS = cast<CapturedStmt>(AStmt);
11176 // 1.2.2 OpenMP Language Terminology
11177 // Structured block - An executable statement with a single entry at the
11178 // top and a single exit at the bottom.
11179 // The point of exit cannot be a branch out of the structured block.
11180 // longjmp() and throw() must not violate the entry/exit criteria.
11181 CS->getCapturedDecl()->setNothrow();
11182 for (int ThisCaptureLevel =
11183 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
11184 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11185 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11186 // 1.2.2 OpenMP Language Terminology
11187 // Structured block - An executable statement with a single entry at the
11188 // top and a single exit at the bottom.
11189 // The point of exit cannot be a branch out of the structured block.
11190 // longjmp() and throw() must not violate the entry/exit criteria.
11191 CS->getCapturedDecl()->setNothrow();
11192 }
11193
11194 OMPLoopDirective::HelperExprs B;
11195 // In presence of clause 'collapse' with number of loops, it will
11196 // define the nested loops number.
11197 unsigned NestedLoopCount = checkOpenMPLoop(
11198 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11199 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11200 VarsWithImplicitDSA, B);
11201 if (NestedLoopCount == 0)
11202 return StmtError();
11203
11204 assert((CurContext->isDependentContext() || B.builtAll()) &&
11205 "omp for loop exprs were not built");
11206
11207 setFunctionHasBranchProtectedScope();
11208 return OMPDistributeParallelForDirective::Create(
11209 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11210 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11211}
11212
11213StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
11214 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11215 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11216 if (!AStmt)
11217 return StmtError();
11218
11219 auto *CS = cast<CapturedStmt>(AStmt);
11220 // 1.2.2 OpenMP Language Terminology
11221 // Structured block - An executable statement with a single entry at the
11222 // top and a single exit at the bottom.
11223 // The point of exit cannot be a branch out of the structured block.
11224 // longjmp() and throw() must not violate the entry/exit criteria.
11225 CS->getCapturedDecl()->setNothrow();
11226 for (int ThisCaptureLevel =
11227 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
11228 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11229 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11230 // 1.2.2 OpenMP Language Terminology
11231 // Structured block - An executable statement with a single entry at the
11232 // top and a single exit at the bottom.
11233 // The point of exit cannot be a branch out of the structured block.
11234 // longjmp() and throw() must not violate the entry/exit criteria.
11235 CS->getCapturedDecl()->setNothrow();
11236 }
11237
11238 OMPLoopDirective::HelperExprs B;
11239 // In presence of clause 'collapse' with number of loops, it will
11240 // define the nested loops number.
11241 unsigned NestedLoopCount = checkOpenMPLoop(
11242 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
11243 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11244 VarsWithImplicitDSA, B);
11245 if (NestedLoopCount == 0)
11246 return StmtError();
11247
11248 assert((CurContext->isDependentContext() || B.builtAll()) &&
11249 "omp for loop exprs were not built");
11250
11251 if (!CurContext->isDependentContext()) {
11252 // Finalize the clauses that need pre-built expressions for CodeGen.
11253 for (OMPClause *C : Clauses) {
11254 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11255 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11256 B.NumIterations, *this, CurScope,
11257 DSAStack))
11258 return StmtError();
11259 }
11260 }
11261
11262 if (checkSimdlenSafelenSpecified(*this, Clauses))
11263 return StmtError();
11264
11265 setFunctionHasBranchProtectedScope();
11266 return OMPDistributeParallelForSimdDirective::Create(
11267 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11268}
11269
11270StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
11271 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11272 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11273 if (!AStmt)
11274 return StmtError();
11275
11276 auto *CS = cast<CapturedStmt>(AStmt);
11277 // 1.2.2 OpenMP Language Terminology
11278 // Structured block - An executable statement with a single entry at the
11279 // top and a single exit at the bottom.
11280 // The point of exit cannot be a branch out of the structured block.
11281 // longjmp() and throw() must not violate the entry/exit criteria.
11282 CS->getCapturedDecl()->setNothrow();
11283 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
11284 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11285 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11286 // 1.2.2 OpenMP Language Terminology
11287 // Structured block - An executable statement with a single entry at the
11288 // top and a single exit at the bottom.
11289 // The point of exit cannot be a branch out of the structured block.
11290 // longjmp() and throw() must not violate the entry/exit criteria.
11291 CS->getCapturedDecl()->setNothrow();
11292 }
11293
11294 OMPLoopDirective::HelperExprs B;
11295 // In presence of clause 'collapse' with number of loops, it will
11296 // define the nested loops number.
11297 unsigned NestedLoopCount =
11298 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
11299 nullptr /*ordered not a clause on distribute*/, CS, *this,
11300 *DSAStack, VarsWithImplicitDSA, B);
11301 if (NestedLoopCount == 0)
11302 return StmtError();
11303
11304 assert((CurContext->isDependentContext() || B.builtAll()) &&
11305 "omp for loop exprs were not built");
11306
11307 if (!CurContext->isDependentContext()) {
11308 // Finalize the clauses that need pre-built expressions for CodeGen.
11309 for (OMPClause *C : Clauses) {
11310 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11311 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11312 B.NumIterations, *this, CurScope,
11313 DSAStack))
11314 return StmtError();
11315 }
11316 }
11317
11318 if (checkSimdlenSafelenSpecified(*this, Clauses))
11319 return StmtError();
11320
11321 setFunctionHasBranchProtectedScope();
11322 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
11323 NestedLoopCount, Clauses, AStmt, B);
11324}
11325
11326StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
11327 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11328 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11329 if (!AStmt)
11330 return StmtError();
11331
11332 auto *CS = cast<CapturedStmt>(AStmt);
11333 // 1.2.2 OpenMP Language Terminology
11334 // Structured block - An executable statement with a single entry at the
11335 // top and a single exit at the bottom.
11336 // The point of exit cannot be a branch out of the structured block.
11337 // longjmp() and throw() must not violate the entry/exit criteria.
11338 CS->getCapturedDecl()->setNothrow();
11339 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
11340 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11341 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11342 // 1.2.2 OpenMP Language Terminology
11343 // Structured block - An executable statement with a single entry at the
11344 // top and a single exit at the bottom.
11345 // The point of exit cannot be a branch out of the structured block.
11346 // longjmp() and throw() must not violate the entry/exit criteria.
11347 CS->getCapturedDecl()->setNothrow();
11348 }
11349
11350 OMPLoopDirective::HelperExprs B;
11351 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11352 // define the nested loops number.
11353 unsigned NestedLoopCount = checkOpenMPLoop(
11354 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
11355 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
11356 VarsWithImplicitDSA, B);
11357 if (NestedLoopCount == 0)
11358 return StmtError();
11359
11360 assert((CurContext->isDependentContext() || B.builtAll()) &&
11361 "omp target parallel for simd loop exprs were not built");
11362
11363 if (!CurContext->isDependentContext()) {
11364 // Finalize the clauses that need pre-built expressions for CodeGen.
11365 for (OMPClause *C : Clauses) {
11366 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11367 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11368 B.NumIterations, *this, CurScope,
11369 DSAStack))
11370 return StmtError();
11371 }
11372 }
11373 if (checkSimdlenSafelenSpecified(*this, Clauses))
11374 return StmtError();
11375
11376 setFunctionHasBranchProtectedScope();
11377 return OMPTargetParallelForSimdDirective::Create(
11378 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11379}
11380
11381StmtResult Sema::ActOnOpenMPTargetSimdDirective(
11382 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11383 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11384 if (!AStmt)
11385 return StmtError();
11386
11387 auto *CS = cast<CapturedStmt>(AStmt);
11388 // 1.2.2 OpenMP Language Terminology
11389 // Structured block - An executable statement with a single entry at the
11390 // top and a single exit at the bottom.
11391 // The point of exit cannot be a branch out of the structured block.
11392 // longjmp() and throw() must not violate the entry/exit criteria.
11393 CS->getCapturedDecl()->setNothrow();
11394 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
11395 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11396 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11397 // 1.2.2 OpenMP Language Terminology
11398 // Structured block - An executable statement with a single entry at the
11399 // top and a single exit at the bottom.
11400 // The point of exit cannot be a branch out of the structured block.
11401 // longjmp() and throw() must not violate the entry/exit criteria.
11402 CS->getCapturedDecl()->setNothrow();
11403 }
11404
11405 OMPLoopDirective::HelperExprs B;
11406 // In presence of clause 'collapse' with number of loops, it will define the
11407 // nested loops number.
11408 unsigned NestedLoopCount =
11409 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
11410 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
11411 VarsWithImplicitDSA, B);
11412 if (NestedLoopCount == 0)
11413 return StmtError();
11414
11415 assert((CurContext->isDependentContext() || B.builtAll()) &&
11416 "omp target simd loop exprs were not built");
11417
11418 if (!CurContext->isDependentContext()) {
11419 // Finalize the clauses that need pre-built expressions for CodeGen.
11420 for (OMPClause *C : Clauses) {
11421 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11422 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11423 B.NumIterations, *this, CurScope,
11424 DSAStack))
11425 return StmtError();
11426 }
11427 }
11428
11429 if (checkSimdlenSafelenSpecified(*this, Clauses))
11430 return StmtError();
11431
11432 setFunctionHasBranchProtectedScope();
11433 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
11434 NestedLoopCount, Clauses, AStmt, B);
11435}
11436
11437StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
11438 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11439 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11440 if (!AStmt)
11441 return StmtError();
11442
11443 auto *CS = cast<CapturedStmt>(AStmt);
11444 // 1.2.2 OpenMP Language Terminology
11445 // Structured block - An executable statement with a single entry at the
11446 // top and a single exit at the bottom.
11447 // The point of exit cannot be a branch out of the structured block.
11448 // longjmp() and throw() must not violate the entry/exit criteria.
11449 CS->getCapturedDecl()->setNothrow();
11450 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
11451 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11452 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11453 // 1.2.2 OpenMP Language Terminology
11454 // Structured block - An executable statement with a single entry at the
11455 // top and a single exit at the bottom.
11456 // The point of exit cannot be a branch out of the structured block.
11457 // longjmp() and throw() must not violate the entry/exit criteria.
11458 CS->getCapturedDecl()->setNothrow();
11459 }
11460
11461 OMPLoopDirective::HelperExprs B;
11462 // In presence of clause 'collapse' with number of loops, it will
11463 // define the nested loops number.
11464 unsigned NestedLoopCount =
11465 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
11466 nullptr /*ordered not a clause on distribute*/, CS, *this,
11467 *DSAStack, VarsWithImplicitDSA, B);
11468 if (NestedLoopCount == 0)
11469 return StmtError();
11470
11471 assert((CurContext->isDependentContext() || B.builtAll()) &&
11472 "omp teams distribute loop exprs were not built");
11473
11474 setFunctionHasBranchProtectedScope();
11475
11476 DSAStack->setParentTeamsRegionLoc(StartLoc);
11477
11478 return OMPTeamsDistributeDirective::Create(
11479 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11480}
11481
11482StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
11483 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11484 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11485 if (!AStmt)
11486 return StmtError();
11487
11488 auto *CS = cast<CapturedStmt>(AStmt);
11489 // 1.2.2 OpenMP Language Terminology
11490 // Structured block - An executable statement with a single entry at the
11491 // top and a single exit at the bottom.
11492 // The point of exit cannot be a branch out of the structured block.
11493 // longjmp() and throw() must not violate the entry/exit criteria.
11494 CS->getCapturedDecl()->setNothrow();
11495 for (int ThisCaptureLevel =
11496 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
11497 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11498 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11499 // 1.2.2 OpenMP Language Terminology
11500 // Structured block - An executable statement with a single entry at the
11501 // top and a single exit at the bottom.
11502 // The point of exit cannot be a branch out of the structured block.
11503 // longjmp() and throw() must not violate the entry/exit criteria.
11504 CS->getCapturedDecl()->setNothrow();
11505 }
11506
11507 OMPLoopDirective::HelperExprs B;
11508 // In presence of clause 'collapse' with number of loops, it will
11509 // define the nested loops number.
11510 unsigned NestedLoopCount = checkOpenMPLoop(
11511 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
11512 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11513 VarsWithImplicitDSA, B);
11514
11515 if (NestedLoopCount == 0)
11516 return StmtError();
11517
11518 assert((CurContext->isDependentContext() || B.builtAll()) &&
11519 "omp teams distribute simd loop exprs were not built");
11520
11521 if (!CurContext->isDependentContext()) {
11522 // Finalize the clauses that need pre-built expressions for CodeGen.
11523 for (OMPClause *C : Clauses) {
11524 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11525 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11526 B.NumIterations, *this, CurScope,
11527 DSAStack))
11528 return StmtError();
11529 }
11530 }
11531
11532 if (checkSimdlenSafelenSpecified(*this, Clauses))
11533 return StmtError();
11534
11535 setFunctionHasBranchProtectedScope();
11536
11537 DSAStack->setParentTeamsRegionLoc(StartLoc);
11538
11539 return OMPTeamsDistributeSimdDirective::Create(
11540 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11541}
11542
11543StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
11544 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11545 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11546 if (!AStmt)
11547 return StmtError();
11548
11549 auto *CS = cast<CapturedStmt>(AStmt);
11550 // 1.2.2 OpenMP Language Terminology
11551 // Structured block - An executable statement with a single entry at the
11552 // top and a single exit at the bottom.
11553 // The point of exit cannot be a branch out of the structured block.
11554 // longjmp() and throw() must not violate the entry/exit criteria.
11555 CS->getCapturedDecl()->setNothrow();
11556
11557 for (int ThisCaptureLevel =
11558 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
11559 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11560 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11561 // 1.2.2 OpenMP Language Terminology
11562 // Structured block - An executable statement with a single entry at the
11563 // top and a single exit at the bottom.
11564 // The point of exit cannot be a branch out of the structured block.
11565 // longjmp() and throw() must not violate the entry/exit criteria.
11566 CS->getCapturedDecl()->setNothrow();
11567 }
11568
11569 OMPLoopDirective::HelperExprs B;
11570 // In presence of clause 'collapse' with number of loops, it will
11571 // define the nested loops number.
11572 unsigned NestedLoopCount = checkOpenMPLoop(
11573 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
11574 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11575 VarsWithImplicitDSA, B);
11576
11577 if (NestedLoopCount == 0)
11578 return StmtError();
11579
11580 assert((CurContext->isDependentContext() || B.builtAll()) &&
11581 "omp for loop exprs were not built");
11582
11583 if (!CurContext->isDependentContext()) {
11584 // Finalize the clauses that need pre-built expressions for CodeGen.
11585 for (OMPClause *C : Clauses) {
11586 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11587 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11588 B.NumIterations, *this, CurScope,
11589 DSAStack))
11590 return StmtError();
11591 }
11592 }
11593
11594 if (checkSimdlenSafelenSpecified(*this, Clauses))
11595 return StmtError();
11596
11597 setFunctionHasBranchProtectedScope();
11598
11599 DSAStack->setParentTeamsRegionLoc(StartLoc);
11600
11601 return OMPTeamsDistributeParallelForSimdDirective::Create(
11602 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11603}
11604
11605StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
11606 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11607 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11608 if (!AStmt)
11609 return StmtError();
11610
11611 auto *CS = cast<CapturedStmt>(AStmt);
11612 // 1.2.2 OpenMP Language Terminology
11613 // Structured block - An executable statement with a single entry at the
11614 // top and a single exit at the bottom.
11615 // The point of exit cannot be a branch out of the structured block.
11616 // longjmp() and throw() must not violate the entry/exit criteria.
11617 CS->getCapturedDecl()->setNothrow();
11618
11619 for (int ThisCaptureLevel =
11620 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
11621 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11622 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11623 // 1.2.2 OpenMP Language Terminology
11624 // Structured block - An executable statement with a single entry at the
11625 // top and a single exit at the bottom.
11626 // The point of exit cannot be a branch out of the structured block.
11627 // longjmp() and throw() must not violate the entry/exit criteria.
11628 CS->getCapturedDecl()->setNothrow();
11629 }
11630
11631 OMPLoopDirective::HelperExprs B;
11632 // In presence of clause 'collapse' with number of loops, it will
11633 // define the nested loops number.
11634 unsigned NestedLoopCount = checkOpenMPLoop(
11635 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11636 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11637 VarsWithImplicitDSA, B);
11638
11639 if (NestedLoopCount == 0)
11640 return StmtError();
11641
11642 assert((CurContext->isDependentContext() || B.builtAll()) &&
11643 "omp for loop exprs were not built");
11644
11645 setFunctionHasBranchProtectedScope();
11646
11647 DSAStack->setParentTeamsRegionLoc(StartLoc);
11648
11649 return OMPTeamsDistributeParallelForDirective::Create(
11650 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11651 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11652}
11653
11654StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
11655 Stmt *AStmt,
11656 SourceLocation StartLoc,
11657 SourceLocation EndLoc) {
11658 if (!AStmt)
11659 return StmtError();
11660
11661 auto *CS = cast<CapturedStmt>(AStmt);
11662 // 1.2.2 OpenMP Language Terminology
11663 // Structured block - An executable statement with a single entry at the
11664 // top and a single exit at the bottom.
11665 // The point of exit cannot be a branch out of the structured block.
11666 // longjmp() and throw() must not violate the entry/exit criteria.
11667 CS->getCapturedDecl()->setNothrow();
11668
11669 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
11670 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11671 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11672 // 1.2.2 OpenMP Language Terminology
11673 // Structured block - An executable statement with a single entry at the
11674 // top and a single exit at the bottom.
11675 // The point of exit cannot be a branch out of the structured block.
11676 // longjmp() and throw() must not violate the entry/exit criteria.
11677 CS->getCapturedDecl()->setNothrow();
11678 }
11679 setFunctionHasBranchProtectedScope();
11680
11681 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
11682 AStmt);
11683}
11684
11685StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
11686 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11687 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11688 if (!AStmt)
11689 return StmtError();
11690
11691 auto *CS = cast<CapturedStmt>(AStmt);
11692 // 1.2.2 OpenMP Language Terminology
11693 // Structured block - An executable statement with a single entry at the
11694 // top and a single exit at the bottom.
11695 // The point of exit cannot be a branch out of the structured block.
11696 // longjmp() and throw() must not violate the entry/exit criteria.
11697 CS->getCapturedDecl()->setNothrow();
11698 for (int ThisCaptureLevel =
11699 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
11700 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11701 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11702 // 1.2.2 OpenMP Language Terminology
11703 // Structured block - An executable statement with a single entry at the
11704 // top and a single exit at the bottom.
11705 // The point of exit cannot be a branch out of the structured block.
11706 // longjmp() and throw() must not violate the entry/exit criteria.
11707 CS->getCapturedDecl()->setNothrow();
11708 }
11709
11710 OMPLoopDirective::HelperExprs B;
11711 // In presence of clause 'collapse' with number of loops, it will
11712 // define the nested loops number.
11713 unsigned NestedLoopCount = checkOpenMPLoop(
11714 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
11715 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11716 VarsWithImplicitDSA, B);
11717 if (NestedLoopCount == 0)
11718 return StmtError();
11719
11720 assert((CurContext->isDependentContext() || B.builtAll()) &&
11721 "omp target teams distribute loop exprs were not built");
11722
11723 setFunctionHasBranchProtectedScope();
11724 return OMPTargetTeamsDistributeDirective::Create(
11725 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11726}
11727
11728StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
11729 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11730 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11731 if (!AStmt)
11732 return StmtError();
11733
11734 auto *CS = cast<CapturedStmt>(AStmt);
11735 // 1.2.2 OpenMP Language Terminology
11736 // Structured block - An executable statement with a single entry at the
11737 // top and a single exit at the bottom.
11738 // The point of exit cannot be a branch out of the structured block.
11739 // longjmp() and throw() must not violate the entry/exit criteria.
11740 CS->getCapturedDecl()->setNothrow();
11741 for (int ThisCaptureLevel =
11742 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
11743 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11744 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11745 // 1.2.2 OpenMP Language Terminology
11746 // Structured block - An executable statement with a single entry at the
11747 // top and a single exit at the bottom.
11748 // The point of exit cannot be a branch out of the structured block.
11749 // longjmp() and throw() must not violate the entry/exit criteria.
11750 CS->getCapturedDecl()->setNothrow();
11751 }
11752
11753 OMPLoopDirective::HelperExprs B;
11754 // In presence of clause 'collapse' with number of loops, it will
11755 // define the nested loops number.
11756 unsigned NestedLoopCount = checkOpenMPLoop(
11757 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11758 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11759 VarsWithImplicitDSA, B);
11760 if (NestedLoopCount == 0)
11761 return StmtError();
11762
11763 assert((CurContext->isDependentContext() || B.builtAll()) &&
11764 "omp target teams distribute parallel for loop exprs were not built");
11765
11766 if (!CurContext->isDependentContext()) {
11767 // Finalize the clauses that need pre-built expressions for CodeGen.
11768 for (OMPClause *C : Clauses) {
11769 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11770 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11771 B.NumIterations, *this, CurScope,
11772 DSAStack))
11773 return StmtError();
11774 }
11775 }
11776
11777 setFunctionHasBranchProtectedScope();
11778 return OMPTargetTeamsDistributeParallelForDirective::Create(
11779 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11780 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11781}
11782
11783StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
11784 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11785 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11786 if (!AStmt)
11787 return StmtError();
11788
11789 auto *CS = cast<CapturedStmt>(AStmt);
11790 // 1.2.2 OpenMP Language Terminology
11791 // Structured block - An executable statement with a single entry at the
11792 // top and a single exit at the bottom.
11793 // The point of exit cannot be a branch out of the structured block.
11794 // longjmp() and throw() must not violate the entry/exit criteria.
11795 CS->getCapturedDecl()->setNothrow();
11796 for (int ThisCaptureLevel = getOpenMPCaptureLevels(
11797 OMPD_target_teams_distribute_parallel_for_simd);
11798 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11799 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11800 // 1.2.2 OpenMP Language Terminology
11801 // Structured block - An executable statement with a single entry at the
11802 // top and a single exit at the bottom.
11803 // The point of exit cannot be a branch out of the structured block.
11804 // longjmp() and throw() must not violate the entry/exit criteria.
11805 CS->getCapturedDecl()->setNothrow();
11806 }
11807
11808 OMPLoopDirective::HelperExprs B;
11809 // In presence of clause 'collapse' with number of loops, it will
11810 // define the nested loops number.
11811 unsigned NestedLoopCount =
11812 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
11813 getCollapseNumberExpr(Clauses),
11814 nullptr /*ordered not a clause on distribute*/, CS, *this,
11815 *DSAStack, VarsWithImplicitDSA, B);
11816 if (NestedLoopCount == 0)
11817 return StmtError();
11818
11819 assert((CurContext->isDependentContext() || B.builtAll()) &&
11820 "omp target teams distribute parallel for simd loop exprs were not "
11821 "built");
11822
11823 if (!CurContext->isDependentContext()) {
11824 // Finalize the clauses that need pre-built expressions for CodeGen.
11825 for (OMPClause *C : Clauses) {
11826 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11827 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11828 B.NumIterations, *this, CurScope,
11829 DSAStack))
11830 return StmtError();
11831 }
11832 }
11833
11834 if (checkSimdlenSafelenSpecified(*this, Clauses))
11835 return StmtError();
11836
11837 setFunctionHasBranchProtectedScope();
11838 return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
11839 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11840}
11841
11842StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
11843 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11844 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11845 if (!AStmt)
11846 return StmtError();
11847
11848 auto *CS = cast<CapturedStmt>(AStmt);
11849 // 1.2.2 OpenMP Language Terminology
11850 // Structured block - An executable statement with a single entry at the
11851 // top and a single exit at the bottom.
11852 // The point of exit cannot be a branch out of the structured block.
11853 // longjmp() and throw() must not violate the entry/exit criteria.
11854 CS->getCapturedDecl()->setNothrow();
11855 for (int ThisCaptureLevel =
11856 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
11857 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11858 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11859 // 1.2.2 OpenMP Language Terminology
11860 // Structured block - An executable statement with a single entry at the
11861 // top and a single exit at the bottom.
11862 // The point of exit cannot be a branch out of the structured block.
11863 // longjmp() and throw() must not violate the entry/exit criteria.
11864 CS->getCapturedDecl()->setNothrow();
11865 }
11866
11867 OMPLoopDirective::HelperExprs B;
11868 // In presence of clause 'collapse' with number of loops, it will
11869 // define the nested loops number.
11870 unsigned NestedLoopCount = checkOpenMPLoop(
11871 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
11872 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11873 VarsWithImplicitDSA, B);
11874 if (NestedLoopCount == 0)
11875 return StmtError();
11876
11877 assert((CurContext->isDependentContext() || B.builtAll()) &&
11878 "omp target teams distribute simd loop exprs were not built");
11879
11880 if (!CurContext->isDependentContext()) {
11881 // Finalize the clauses that need pre-built expressions for CodeGen.
11882 for (OMPClause *C : Clauses) {
11883 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11884 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11885 B.NumIterations, *this, CurScope,
11886 DSAStack))
11887 return StmtError();
11888 }
11889 }
11890
11891 if (checkSimdlenSafelenSpecified(*this, Clauses))
11892 return StmtError();
11893
11894 setFunctionHasBranchProtectedScope();
11895 return OMPTargetTeamsDistributeSimdDirective::Create(
11896 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11897}
11898
11899OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
11900 SourceLocation StartLoc,
11901 SourceLocation LParenLoc,
11902 SourceLocation EndLoc) {
11903 OMPClause *Res = nullptr;
11904 switch (Kind) {
11905 case OMPC_final:
11906 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
11907 break;
11908 case OMPC_num_threads:
11909 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
11910 break;
11911 case OMPC_safelen:
11912 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
11913 break;
11914 case OMPC_simdlen:
11915 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
11916 break;
11917 case OMPC_allocator:
11918 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
11919 break;
11920 case OMPC_collapse:
11921 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
11922 break;
11923 case OMPC_ordered:
11924 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
11925 break;
11926 case OMPC_num_teams:
11927 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
11928 break;
11929 case OMPC_thread_limit:
11930 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
11931 break;
11932 case OMPC_priority:
11933 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
11934 break;
11935 case OMPC_grainsize:
11936 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
11937 break;
11938 case OMPC_num_tasks:
11939 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
11940 break;
11941 case OMPC_hint:
11942 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
11943 break;
11944 case OMPC_depobj:
11945 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
11946 break;
11947 case OMPC_detach:
11948 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
11949 break;
11950 case OMPC_device:
11951 case OMPC_if:
11952 case OMPC_default:
11953 case OMPC_proc_bind:
11954 case OMPC_schedule:
11955 case OMPC_private:
11956 case OMPC_firstprivate:
11957 case OMPC_lastprivate:
11958 case OMPC_shared:
11959 case OMPC_reduction:
11960 case OMPC_task_reduction:
11961 case OMPC_in_reduction:
11962 case OMPC_linear:
11963 case OMPC_aligned:
11964 case OMPC_copyin:
11965 case OMPC_copyprivate:
11966 case OMPC_nowait:
11967 case OMPC_untied:
11968 case OMPC_mergeable:
11969 case OMPC_threadprivate:
11970 case OMPC_allocate:
11971 case OMPC_flush:
11972 case OMPC_read:
11973 case OMPC_write:
11974 case OMPC_update:
11975 case OMPC_capture:
11976 case OMPC_seq_cst:
11977 case OMPC_acq_rel:
11978 case OMPC_acquire:
11979 case OMPC_release:
11980 case OMPC_relaxed:
11981 case OMPC_depend:
11982 case OMPC_threads:
11983 case OMPC_simd:
11984 case OMPC_map:
11985 case OMPC_nogroup:
11986 case OMPC_dist_schedule:
11987 case OMPC_defaultmap:
11988 case OMPC_unknown:
11989 case OMPC_uniform:
11990 case OMPC_to:
11991 case OMPC_from:
11992 case OMPC_use_device_ptr:
11993 case OMPC_use_device_addr:
11994 case OMPC_is_device_ptr:
11995 case OMPC_unified_address:
11996 case OMPC_unified_shared_memory:
11997 case OMPC_reverse_offload:
11998 case OMPC_dynamic_allocators:
11999 case OMPC_atomic_default_mem_order:
12000 case OMPC_device_type:
12001 case OMPC_match:
12002 case OMPC_nontemporal:
12003 case OMPC_order:
12004 case OMPC_destroy:
12005 case OMPC_inclusive:
12006 case OMPC_exclusive:
12007 case OMPC_uses_allocators:
12008 case OMPC_affinity:
12009 default:
12010 llvm_unreachable("Clause is not allowed.");
12011 }
12012 return Res;
12013}
12014
12015// An OpenMP directive such as 'target parallel' has two captured regions:
12016// for the 'target' and 'parallel' respectively. This function returns
12017// the region in which to capture expressions associated with a clause.
12018// A return value of OMPD_unknown signifies that the expression should not
12019// be captured.
12020static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
12021 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
12022 OpenMPDirectiveKind NameModifier = OMPD_unknown) {
12023 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
12024 switch (CKind) {
12025 case OMPC_if:
12026 switch (DKind) {
12027 case OMPD_target_parallel_for_simd:
12028 if (OpenMPVersion >= 50 &&
12029 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
12030 CaptureRegion = OMPD_parallel;
12031 break;
12032 }
12033 LLVM_FALLTHROUGH;
12034 case OMPD_target_parallel:
12035 case OMPD_target_parallel_for:
12036 // If this clause applies to the nested 'parallel' region, capture within
12037 // the 'target' region, otherwise do not capture.
12038 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
12039 CaptureRegion = OMPD_target;
12040 break;
12041 case OMPD_target_teams_distribute_parallel_for_simd:
12042 if (OpenMPVersion >= 50 &&
12043 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
12044 CaptureRegion = OMPD_parallel;
12045 break;
12046 }
12047 LLVM_FALLTHROUGH;
12048 case OMPD_target_teams_distribute_parallel_for:
12049 // If this clause applies to the nested 'parallel' region, capture within
12050 // the 'teams' region, otherwise do not capture.
12051 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
12052 CaptureRegion = OMPD_teams;
12053 break;
12054 case OMPD_teams_distribute_parallel_for_simd:
12055 if (OpenMPVersion >= 50 &&
12056 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
12057 CaptureRegion = OMPD_parallel;
12058 break;
12059 }
12060 LLVM_FALLTHROUGH;
12061 case OMPD_teams_distribute_parallel_for:
12062 CaptureRegion = OMPD_teams;
12063 break;
12064 case OMPD_target_update:
12065 case OMPD_target_enter_data:
12066 case OMPD_target_exit_data:
12067 CaptureRegion = OMPD_task;
12068 break;
12069 case OMPD_parallel_master_taskloop:
12070 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
12071 CaptureRegion = OMPD_parallel;
12072 break;
12073 case OMPD_parallel_master_taskloop_simd:
12074 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
12075 NameModifier == OMPD_taskloop) {
12076 CaptureRegion = OMPD_parallel;
12077 break;
12078 }
12079 if (OpenMPVersion <= 45)
12080 break;
12081 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12082 CaptureRegion = OMPD_taskloop;
12083 break;
12084 case OMPD_parallel_for_simd:
12085 if (OpenMPVersion <= 45)
12086 break;
12087 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12088 CaptureRegion = OMPD_parallel;
12089 break;
12090 case OMPD_taskloop_simd:
12091 case OMPD_master_taskloop_simd:
12092 if (OpenMPVersion <= 45)
12093 break;
12094 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12095 CaptureRegion = OMPD_taskloop;
12096 break;
12097 case OMPD_distribute_parallel_for_simd:
12098 if (OpenMPVersion <= 45)
12099 break;
12100 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12101 CaptureRegion = OMPD_parallel;
12102 break;
12103 case OMPD_target_simd:
12104 if (OpenMPVersion >= 50 &&
12105 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
12106 CaptureRegion = OMPD_target;
12107 break;
12108 case OMPD_teams_distribute_simd:
12109 case OMPD_target_teams_distribute_simd:
12110 if (OpenMPVersion >= 50 &&
12111 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
12112 CaptureRegion = OMPD_teams;
12113 break;
12114 case OMPD_cancel:
12115 case OMPD_parallel:
12116 case OMPD_parallel_master:
12117 case OMPD_parallel_sections:
12118 case OMPD_parallel_for:
12119 case OMPD_target:
12120 case OMPD_target_teams:
12121 case OMPD_target_teams_distribute:
12122 case OMPD_distribute_parallel_for:
12123 case OMPD_task:
12124 case OMPD_taskloop:
12125 case OMPD_master_taskloop:
12126 case OMPD_target_data:
12127 case OMPD_simd:
12128 case OMPD_for_simd:
12129 case OMPD_distribute_simd:
12130 // Do not capture if-clause expressions.
12131 break;
12132 case OMPD_threadprivate:
12133 case OMPD_allocate:
12134 case OMPD_taskyield:
12135 case OMPD_barrier:
12136 case OMPD_taskwait:
12137 case OMPD_cancellation_point:
12138 case OMPD_flush:
12139 case OMPD_depobj:
12140 case OMPD_scan:
12141 case OMPD_declare_reduction:
12142 case OMPD_declare_mapper:
12143 case OMPD_declare_simd:
12144 case OMPD_declare_variant:
12145 case OMPD_begin_declare_variant:
12146 case OMPD_end_declare_variant:
12147 case OMPD_declare_target:
12148 case OMPD_end_declare_target:
12149 case OMPD_teams:
12150 case OMPD_for:
12151 case OMPD_sections:
12152 case OMPD_section:
12153 case OMPD_single:
12154 case OMPD_master:
12155 case OMPD_critical:
12156 case OMPD_taskgroup:
12157 case OMPD_distribute:
12158 case OMPD_ordered:
12159 case OMPD_atomic:
12160 case OMPD_teams_distribute:
12161 case OMPD_requires:
12162 llvm_unreachable("Unexpected OpenMP directive with if-clause");
12163 case OMPD_unknown:
12164 default:
12165 llvm_unreachable("Unknown OpenMP directive");
12166 }
12167 break;
12168 case OMPC_num_threads:
12169 switch (DKind) {
12170 case OMPD_target_parallel:
12171 case OMPD_target_parallel_for:
12172 case OMPD_target_parallel_for_simd:
12173 CaptureRegion = OMPD_target;
12174 break;
12175 case OMPD_teams_distribute_parallel_for:
12176 case OMPD_teams_distribute_parallel_for_simd:
12177 case OMPD_target_teams_distribute_parallel_for:
12178 case OMPD_target_teams_distribute_parallel_for_simd:
12179 CaptureRegion = OMPD_teams;
12180 break;
12181 case OMPD_parallel:
12182 case OMPD_parallel_master:
12183 case OMPD_parallel_sections:
12184 case OMPD_parallel_for:
12185 case OMPD_parallel_for_simd:
12186 case OMPD_distribute_parallel_for:
12187 case OMPD_distribute_parallel_for_simd:
12188 case OMPD_parallel_master_taskloop:
12189 case OMPD_parallel_master_taskloop_simd:
12190 // Do not capture num_threads-clause expressions.
12191 break;
12192 case OMPD_target_data:
12193 case OMPD_target_enter_data:
12194 case OMPD_target_exit_data:
12195 case OMPD_target_update:
12196 case OMPD_target:
12197 case OMPD_target_simd:
12198 case OMPD_target_teams:
12199 case OMPD_target_teams_distribute:
12200 case OMPD_target_teams_distribute_simd:
12201 case OMPD_cancel:
12202 case OMPD_task:
12203 case OMPD_taskloop:
12204 case OMPD_taskloop_simd:
12205 case OMPD_master_taskloop:
12206 case OMPD_master_taskloop_simd:
12207 case OMPD_threadprivate:
12208 case OMPD_allocate:
12209 case OMPD_taskyield:
12210 case OMPD_barrier:
12211 case OMPD_taskwait:
12212 case OMPD_cancellation_point:
12213 case OMPD_flush:
12214 case OMPD_depobj:
12215 case OMPD_scan:
12216 case OMPD_declare_reduction:
12217 case OMPD_declare_mapper:
12218 case OMPD_declare_simd:
12219 case OMPD_declare_variant:
12220 case OMPD_begin_declare_variant:
12221 case OMPD_end_declare_variant:
12222 case OMPD_declare_target:
12223 case OMPD_end_declare_target:
12224 case OMPD_teams:
12225 case OMPD_simd:
12226 case OMPD_for:
12227 case OMPD_for_simd:
12228 case OMPD_sections:
12229 case OMPD_section:
12230 case OMPD_single:
12231 case OMPD_master:
12232 case OMPD_critical:
12233 case OMPD_taskgroup:
12234 case OMPD_distribute:
12235 case OMPD_ordered:
12236 case OMPD_atomic:
12237 case OMPD_distribute_simd:
12238 case OMPD_teams_distribute:
12239 case OMPD_teams_distribute_simd:
12240 case OMPD_requires:
12241 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
12242 case OMPD_unknown:
12243 default:
12244 llvm_unreachable("Unknown OpenMP directive");
12245 }
12246 break;
12247 case OMPC_num_teams:
12248 switch (DKind) {
12249 case OMPD_target_teams:
12250 case OMPD_target_teams_distribute:
12251 case OMPD_target_teams_distribute_simd:
12252 case OMPD_target_teams_distribute_parallel_for:
12253 case OMPD_target_teams_distribute_parallel_for_simd:
12254 CaptureRegion = OMPD_target;
12255 break;
12256 case OMPD_teams_distribute_parallel_for:
12257 case OMPD_teams_distribute_parallel_for_simd:
12258 case OMPD_teams:
12259 case OMPD_teams_distribute:
12260 case OMPD_teams_distribute_simd:
12261 // Do not capture num_teams-clause expressions.
12262 break;
12263 case OMPD_distribute_parallel_for:
12264 case OMPD_distribute_parallel_for_simd:
12265 case OMPD_task:
12266 case OMPD_taskloop:
12267 case OMPD_taskloop_simd:
12268 case OMPD_master_taskloop:
12269 case OMPD_master_taskloop_simd:
12270 case OMPD_parallel_master_taskloop:
12271 case OMPD_parallel_master_taskloop_simd:
12272 case OMPD_target_data:
12273 case OMPD_target_enter_data:
12274 case OMPD_target_exit_data:
12275 case OMPD_target_update:
12276 case OMPD_cancel:
12277 case OMPD_parallel:
12278 case OMPD_parallel_master:
12279 case OMPD_parallel_sections:
12280 case OMPD_parallel_for:
12281 case OMPD_parallel_for_simd:
12282 case OMPD_target:
12283 case OMPD_target_simd:
12284 case OMPD_target_parallel:
12285 case OMPD_target_parallel_for:
12286 case OMPD_target_parallel_for_simd:
12287 case OMPD_threadprivate:
12288 case OMPD_allocate:
12289 case OMPD_taskyield:
12290 case OMPD_barrier:
12291 case OMPD_taskwait:
12292 case OMPD_cancellation_point:
12293 case OMPD_flush:
12294 case OMPD_depobj:
12295 case OMPD_scan:
12296 case OMPD_declare_reduction:
12297 case OMPD_declare_mapper:
12298 case OMPD_declare_simd:
12299 case OMPD_declare_variant:
12300 case OMPD_begin_declare_variant:
12301 case OMPD_end_declare_variant:
12302 case OMPD_declare_target:
12303 case OMPD_end_declare_target:
12304 case OMPD_simd:
12305 case OMPD_for:
12306 case OMPD_for_simd:
12307 case OMPD_sections:
12308 case OMPD_section:
12309 case OMPD_single:
12310 case OMPD_master:
12311 case OMPD_critical:
12312 case OMPD_taskgroup:
12313 case OMPD_distribute:
12314 case OMPD_ordered:
12315 case OMPD_atomic:
12316 case OMPD_distribute_simd:
12317 case OMPD_requires:
12318 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
12319 case OMPD_unknown:
12320 default:
12321 llvm_unreachable("Unknown OpenMP directive");
12322 }
12323 break;
12324 case OMPC_thread_limit:
12325 switch (DKind) {
12326 case OMPD_target_teams:
12327 case OMPD_target_teams_distribute:
12328 case OMPD_target_teams_distribute_simd:
12329 case OMPD_target_teams_distribute_parallel_for:
12330 case OMPD_target_teams_distribute_parallel_for_simd:
12331 CaptureRegion = OMPD_target;
12332 break;
12333 case OMPD_teams_distribute_parallel_for:
12334 case OMPD_teams_distribute_parallel_for_simd:
12335 case OMPD_teams:
12336 case OMPD_teams_distribute:
12337 case OMPD_teams_distribute_simd:
12338 // Do not capture thread_limit-clause expressions.
12339 break;
12340 case OMPD_distribute_parallel_for:
12341 case OMPD_distribute_parallel_for_simd:
12342 case OMPD_task:
12343 case OMPD_taskloop:
12344 case OMPD_taskloop_simd:
12345 case OMPD_master_taskloop:
12346 case OMPD_master_taskloop_simd:
12347 case OMPD_parallel_master_taskloop:
12348 case OMPD_parallel_master_taskloop_simd:
12349 case OMPD_target_data:
12350 case OMPD_target_enter_data:
12351 case OMPD_target_exit_data:
12352 case OMPD_target_update:
12353 case OMPD_cancel:
12354 case OMPD_parallel:
12355 case OMPD_parallel_master:
12356 case OMPD_parallel_sections:
12357 case OMPD_parallel_for:
12358 case OMPD_parallel_for_simd:
12359 case OMPD_target:
12360 case OMPD_target_simd:
12361 case OMPD_target_parallel:
12362 case OMPD_target_parallel_for:
12363 case OMPD_target_parallel_for_simd:
12364 case OMPD_threadprivate:
12365 case OMPD_allocate:
12366 case OMPD_taskyield:
12367 case OMPD_barrier:
12368 case OMPD_taskwait:
12369 case OMPD_cancellation_point:
12370 case OMPD_flush:
12371 case OMPD_depobj:
12372 case OMPD_scan:
12373 case OMPD_declare_reduction:
12374 case OMPD_declare_mapper:
12375 case OMPD_declare_simd:
12376 case OMPD_declare_variant:
12377 case OMPD_begin_declare_variant:
12378 case OMPD_end_declare_variant:
12379 case OMPD_declare_target:
12380 case OMPD_end_declare_target:
12381 case OMPD_simd:
12382 case OMPD_for:
12383 case OMPD_for_simd:
12384 case OMPD_sections:
12385 case OMPD_section:
12386 case OMPD_single:
12387 case OMPD_master:
12388 case OMPD_critical:
12389 case OMPD_taskgroup:
12390 case OMPD_distribute:
12391 case OMPD_ordered:
12392 case OMPD_atomic:
12393 case OMPD_distribute_simd:
12394 case OMPD_requires:
12395 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
12396 case OMPD_unknown:
12397 default:
12398 llvm_unreachable("Unknown OpenMP directive");
12399 }
12400 break;
12401 case OMPC_schedule:
12402 switch (DKind) {
12403 case OMPD_parallel_for:
12404 case OMPD_parallel_for_simd:
12405 case OMPD_distribute_parallel_for:
12406 case OMPD_distribute_parallel_for_simd:
12407 case OMPD_teams_distribute_parallel_for:
12408 case OMPD_teams_distribute_parallel_for_simd:
12409 case OMPD_target_parallel_for:
12410 case OMPD_target_parallel_for_simd:
12411 case OMPD_target_teams_distribute_parallel_for:
12412 case OMPD_target_teams_distribute_parallel_for_simd:
12413 CaptureRegion = OMPD_parallel;
12414 break;
12415 case OMPD_for:
12416 case OMPD_for_simd:
12417 // Do not capture schedule-clause expressions.
12418 break;
12419 case OMPD_task:
12420 case OMPD_taskloop:
12421 case OMPD_taskloop_simd:
12422 case OMPD_master_taskloop:
12423 case OMPD_master_taskloop_simd:
12424 case OMPD_parallel_master_taskloop:
12425 case OMPD_parallel_master_taskloop_simd:
12426 case OMPD_target_data:
12427 case OMPD_target_enter_data:
12428 case OMPD_target_exit_data:
12429 case OMPD_target_update:
12430 case OMPD_teams:
12431 case OMPD_teams_distribute:
12432 case OMPD_teams_distribute_simd:
12433 case OMPD_target_teams_distribute:
12434 case OMPD_target_teams_distribute_simd:
12435 case OMPD_target:
12436 case OMPD_target_simd:
12437 case OMPD_target_parallel:
12438 case OMPD_cancel:
12439 case OMPD_parallel:
12440 case OMPD_parallel_master:
12441 case OMPD_parallel_sections:
12442 case OMPD_threadprivate:
12443 case OMPD_allocate:
12444 case OMPD_taskyield:
12445 case OMPD_barrier:
12446 case OMPD_taskwait:
12447 case OMPD_cancellation_point:
12448 case OMPD_flush:
12449 case OMPD_depobj:
12450 case OMPD_scan:
12451 case OMPD_declare_reduction:
12452 case OMPD_declare_mapper:
12453 case OMPD_declare_simd:
12454 case OMPD_declare_variant:
12455 case OMPD_begin_declare_variant:
12456 case OMPD_end_declare_variant:
12457 case OMPD_declare_target:
12458 case OMPD_end_declare_target:
12459 case OMPD_simd:
12460 case OMPD_sections:
12461 case OMPD_section:
12462 case OMPD_single:
12463 case OMPD_master:
12464 case OMPD_critical:
12465 case OMPD_taskgroup:
12466 case OMPD_distribute:
12467 case OMPD_ordered:
12468 case OMPD_atomic:
12469 case OMPD_distribute_simd:
12470 case OMPD_target_teams:
12471 case OMPD_requires:
12472 llvm_unreachable("Unexpected OpenMP directive with schedule clause");
12473 case OMPD_unknown:
12474 default:
12475 llvm_unreachable("Unknown OpenMP directive");
12476 }
12477 break;
12478 case OMPC_dist_schedule:
12479 switch (DKind) {
12480 case OMPD_teams_distribute_parallel_for:
12481 case OMPD_teams_distribute_parallel_for_simd:
12482 case OMPD_teams_distribute:
12483 case OMPD_teams_distribute_simd:
12484 case OMPD_target_teams_distribute_parallel_for:
12485 case OMPD_target_teams_distribute_parallel_for_simd:
12486 case OMPD_target_teams_distribute:
12487 case OMPD_target_teams_distribute_simd:
12488 CaptureRegion = OMPD_teams;
12489 break;
12490 case OMPD_distribute_parallel_for:
12491 case OMPD_distribute_parallel_for_simd:
12492 case OMPD_distribute:
12493 case OMPD_distribute_simd:
12494 // Do not capture thread_limit-clause expressions.
12495 break;
12496 case OMPD_parallel_for:
12497 case OMPD_parallel_for_simd:
12498 case OMPD_target_parallel_for_simd:
12499 case OMPD_target_parallel_for:
12500 case OMPD_task:
12501 case OMPD_taskloop:
12502 case OMPD_taskloop_simd:
12503 case OMPD_master_taskloop:
12504 case OMPD_master_taskloop_simd:
12505 case OMPD_parallel_master_taskloop:
12506 case OMPD_parallel_master_taskloop_simd:
12507 case OMPD_target_data:
12508 case OMPD_target_enter_data:
12509 case OMPD_target_exit_data:
12510 case OMPD_target_update:
12511 case OMPD_teams:
12512 case OMPD_target:
12513 case OMPD_target_simd:
12514 case OMPD_target_parallel:
12515 case OMPD_cancel:
12516 case OMPD_parallel:
12517 case OMPD_parallel_master:
12518 case OMPD_parallel_sections:
12519 case OMPD_threadprivate:
12520 case OMPD_allocate:
12521 case OMPD_taskyield:
12522 case OMPD_barrier:
12523 case OMPD_taskwait:
12524 case OMPD_cancellation_point:
12525 case OMPD_flush:
12526 case OMPD_depobj:
12527 case OMPD_scan:
12528 case OMPD_declare_reduction:
12529 case OMPD_declare_mapper:
12530 case OMPD_declare_simd:
12531 case OMPD_declare_variant:
12532 case OMPD_begin_declare_variant:
12533 case OMPD_end_declare_variant:
12534 case OMPD_declare_target:
12535 case OMPD_end_declare_target:
12536 case OMPD_simd:
12537 case OMPD_for:
12538 case OMPD_for_simd:
12539 case OMPD_sections:
12540 case OMPD_section:
12541 case OMPD_single:
12542 case OMPD_master:
12543 case OMPD_critical:
12544 case OMPD_taskgroup:
12545 case OMPD_ordered:
12546 case OMPD_atomic:
12547 case OMPD_target_teams:
12548 case OMPD_requires:
12549 llvm_unreachable("Unexpected OpenMP directive with schedule clause");
12550 case OMPD_unknown:
12551 default:
12552 llvm_unreachable("Unknown OpenMP directive");
12553 }
12554 break;
12555 case OMPC_device:
12556 switch (DKind) {
12557 case OMPD_target_update:
12558 case OMPD_target_enter_data:
12559 case OMPD_target_exit_data:
12560 case OMPD_target:
12561 case OMPD_target_simd:
12562 case OMPD_target_teams:
12563 case OMPD_target_parallel:
12564 case OMPD_target_teams_distribute:
12565 case OMPD_target_teams_distribute_simd:
12566 case OMPD_target_parallel_for:
12567 case OMPD_target_parallel_for_simd:
12568 case OMPD_target_teams_distribute_parallel_for:
12569 case OMPD_target_teams_distribute_parallel_for_simd:
12570 CaptureRegion = OMPD_task;
12571 break;
12572 case OMPD_target_data:
12573 // Do not capture device-clause expressions.
12574 break;
12575 case OMPD_teams_distribute_parallel_for:
12576 case OMPD_teams_distribute_parallel_for_simd:
12577 case OMPD_teams:
12578 case OMPD_teams_distribute:
12579 case OMPD_teams_distribute_simd:
12580 case OMPD_distribute_parallel_for:
12581 case OMPD_distribute_parallel_for_simd:
12582 case OMPD_task:
12583 case OMPD_taskloop:
12584 case OMPD_taskloop_simd:
12585 case OMPD_master_taskloop:
12586 case OMPD_master_taskloop_simd:
12587 case OMPD_parallel_master_taskloop:
12588 case OMPD_parallel_master_taskloop_simd:
12589 case OMPD_cancel:
12590 case OMPD_parallel:
12591 case OMPD_parallel_master:
12592 case OMPD_parallel_sections:
12593 case OMPD_parallel_for:
12594 case OMPD_parallel_for_simd:
12595 case OMPD_threadprivate:
12596 case OMPD_allocate:
12597 case OMPD_taskyield:
12598 case OMPD_barrier:
12599 case OMPD_taskwait:
12600 case OMPD_cancellation_point:
12601 case OMPD_flush:
12602 case OMPD_depobj:
12603 case OMPD_scan:
12604 case OMPD_declare_reduction:
12605 case OMPD_declare_mapper:
12606 case OMPD_declare_simd:
12607 case OMPD_declare_variant:
12608 case OMPD_begin_declare_variant:
12609 case OMPD_end_declare_variant:
12610 case OMPD_declare_target:
12611 case OMPD_end_declare_target:
12612 case OMPD_simd:
12613 case OMPD_for:
12614 case OMPD_for_simd:
12615 case OMPD_sections:
12616 case OMPD_section:
12617 case OMPD_single:
12618 case OMPD_master:
12619 case OMPD_critical:
12620 case OMPD_taskgroup:
12621 case OMPD_distribute:
12622 case OMPD_ordered:
12623 case OMPD_atomic:
12624 case OMPD_distribute_simd:
12625 case OMPD_requires:
12626 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
12627 case OMPD_unknown:
12628 default:
12629 llvm_unreachable("Unknown OpenMP directive");
12630 }
12631 break;
12632 case OMPC_grainsize:
12633 case OMPC_num_tasks:
12634 case OMPC_final:
12635 case OMPC_priority:
12636 switch (DKind) {
12637 case OMPD_task:
12638 case OMPD_taskloop:
12639 case OMPD_taskloop_simd:
12640 case OMPD_master_taskloop:
12641 case OMPD_master_taskloop_simd:
12642 break;
12643 case OMPD_parallel_master_taskloop:
12644 case OMPD_parallel_master_taskloop_simd:
12645 CaptureRegion = OMPD_parallel;
12646 break;
12647 case OMPD_target_update:
12648 case OMPD_target_enter_data:
12649 case OMPD_target_exit_data:
12650 case OMPD_target:
12651 case OMPD_target_simd:
12652 case OMPD_target_teams:
12653 case OMPD_target_parallel:
12654 case OMPD_target_teams_distribute:
12655 case OMPD_target_teams_distribute_simd:
12656 case OMPD_target_parallel_for:
12657 case OMPD_target_parallel_for_simd:
12658 case OMPD_target_teams_distribute_parallel_for:
12659 case OMPD_target_teams_distribute_parallel_for_simd:
12660 case OMPD_target_data:
12661 case OMPD_teams_distribute_parallel_for:
12662 case OMPD_teams_distribute_parallel_for_simd:
12663 case OMPD_teams:
12664 case OMPD_teams_distribute:
12665 case OMPD_teams_distribute_simd:
12666 case OMPD_distribute_parallel_for:
12667 case OMPD_distribute_parallel_for_simd:
12668 case OMPD_cancel:
12669 case OMPD_parallel:
12670 case OMPD_parallel_master:
12671 case OMPD_parallel_sections:
12672 case OMPD_parallel_for:
12673 case OMPD_parallel_for_simd:
12674 case OMPD_threadprivate:
12675 case OMPD_allocate:
12676 case OMPD_taskyield:
12677 case OMPD_barrier:
12678 case OMPD_taskwait:
12679 case OMPD_cancellation_point:
12680 case OMPD_flush:
12681 case OMPD_depobj:
12682 case OMPD_scan:
12683 case OMPD_declare_reduction:
12684 case OMPD_declare_mapper:
12685 case OMPD_declare_simd:
12686 case OMPD_declare_variant:
12687 case OMPD_begin_declare_variant:
12688 case OMPD_end_declare_variant:
12689 case OMPD_declare_target:
12690 case OMPD_end_declare_target:
12691 case OMPD_simd:
12692 case OMPD_for:
12693 case OMPD_for_simd:
12694 case OMPD_sections:
12695 case OMPD_section:
12696 case OMPD_single:
12697 case OMPD_master:
12698 case OMPD_critical:
12699 case OMPD_taskgroup:
12700 case OMPD_distribute:
12701 case OMPD_ordered:
12702 case OMPD_atomic:
12703 case OMPD_distribute_simd:
12704 case OMPD_requires:
12705 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause");
12706 case OMPD_unknown:
12707 default:
12708 llvm_unreachable("Unknown OpenMP directive");
12709 }
12710 break;
12711 case OMPC_firstprivate:
12712 case OMPC_lastprivate:
12713 case OMPC_reduction:
12714 case OMPC_task_reduction:
12715 case OMPC_in_reduction:
12716 case OMPC_linear:
12717 case OMPC_default:
12718 case OMPC_proc_bind:
12719 case OMPC_safelen:
12720 case OMPC_simdlen:
12721 case OMPC_allocator:
12722 case OMPC_collapse:
12723 case OMPC_private:
12724 case OMPC_shared:
12725 case OMPC_aligned:
12726 case OMPC_copyin:
12727 case OMPC_copyprivate:
12728 case OMPC_ordered:
12729 case OMPC_nowait:
12730 case OMPC_untied:
12731 case OMPC_mergeable:
12732 case OMPC_threadprivate:
12733 case OMPC_allocate:
12734 case OMPC_flush:
12735 case OMPC_depobj:
12736 case OMPC_read:
12737 case OMPC_write:
12738 case OMPC_update:
12739 case OMPC_capture:
12740 case OMPC_seq_cst:
12741 case OMPC_acq_rel:
12742 case OMPC_acquire:
12743 case OMPC_release:
12744 case OMPC_relaxed:
12745 case OMPC_depend:
12746 case OMPC_threads:
12747 case OMPC_simd:
12748 case OMPC_map:
12749 case OMPC_nogroup:
12750 case OMPC_hint:
12751 case OMPC_defaultmap:
12752 case OMPC_unknown:
12753 case OMPC_uniform:
12754 case OMPC_to:
12755 case OMPC_from:
12756 case OMPC_use_device_ptr:
12757 case OMPC_use_device_addr:
12758 case OMPC_is_device_ptr:
12759 case OMPC_unified_address:
12760 case OMPC_unified_shared_memory:
12761 case OMPC_reverse_offload:
12762 case OMPC_dynamic_allocators:
12763 case OMPC_atomic_default_mem_order:
12764 case OMPC_device_type:
12765 case OMPC_match:
12766 case OMPC_nontemporal:
12767 case OMPC_order:
12768 case OMPC_destroy:
12769 case OMPC_detach:
12770 case OMPC_inclusive:
12771 case OMPC_exclusive:
12772 case OMPC_uses_allocators:
12773 case OMPC_affinity:
12774 default:
12775 llvm_unreachable("Unexpected OpenMP clause.");
12776 }
12777 return CaptureRegion;
12778}
12779
12780OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
12781 Expr *Condition, SourceLocation StartLoc,
12782 SourceLocation LParenLoc,
12783 SourceLocation NameModifierLoc,
12784 SourceLocation ColonLoc,
12785 SourceLocation EndLoc) {
12786 Expr *ValExpr = Condition;
12787 Stmt *HelperValStmt = nullptr;
12788 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
12789 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
12790 !Condition->isInstantiationDependent() &&
12791 !Condition->containsUnexpandedParameterPack()) {
12792 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
12793 if (Val.isInvalid())
12794 return nullptr;
12795
12796 ValExpr = Val.get();
12797
12798 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12799 CaptureRegion = getOpenMPCaptureRegionForClause(
12800 DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
12801 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12802 ValExpr = MakeFullExpr(ValExpr).get();
12803 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12804 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12805 HelperValStmt = buildPreInits(Context, Captures);
12806 }
12807 }
12808
12809 return new (Context)
12810 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
12811 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
12812}
12813
12814OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
12815 SourceLocation StartLoc,
12816 SourceLocation LParenLoc,
12817 SourceLocation EndLoc) {
12818 Expr *ValExpr = Condition;
12819 Stmt *HelperValStmt = nullptr;
12820 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
12821 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
12822 !Condition->isInstantiationDependent() &&
12823 !Condition->containsUnexpandedParameterPack()) {
12824 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
12825 if (Val.isInvalid())
12826 return nullptr;
12827
12828 ValExpr = MakeFullExpr(Val.get()).get();
12829
12830 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12831 CaptureRegion =
12832 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
12833 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12834 ValExpr = MakeFullExpr(ValExpr).get();
12835 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12836 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12837 HelperValStmt = buildPreInits(Context, Captures);
12838 }
12839 }
12840
12841 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
12842 StartLoc, LParenLoc, EndLoc);
12843}
12844
12845ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
12846 Expr *Op) {
12847 if (!Op)
12848 return ExprError();
12849
12850 class IntConvertDiagnoser : public ICEConvertDiagnoser {
12851 public:
12852 IntConvertDiagnoser()
12853 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
12854 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
12855 QualType T) override {
12856 return S.Diag(Loc, diag::err_omp_not_integral) << T;
12857 }
12858 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
12859 QualType T) override {
12860 return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
12861 }
12862 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
12863 QualType T,
12864 QualType ConvTy) override {
12865 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
12866 }
12867 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
12868 QualType ConvTy) override {
12869 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
12870 << ConvTy->isEnumeralType() << ConvTy;
12871 }
12872 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
12873 QualType T) override {
12874 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
12875 }
12876 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
12877 QualType ConvTy) override {
12878 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
12879 << ConvTy->isEnumeralType() << ConvTy;
12880 }
12881 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
12882 QualType) override {
12883 llvm_unreachable("conversion functions are permitted");
12884 }
12885 } ConvertDiagnoser;
12886 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
12887}
12888
12889static bool
12890isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
12891 bool StrictlyPositive, bool BuildCapture = false,
12892 OpenMPDirectiveKind DKind = OMPD_unknown,
12893 OpenMPDirectiveKind *CaptureRegion = nullptr,
12894 Stmt **HelperValStmt = nullptr) {
12895 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
12896 !ValExpr->isInstantiationDependent()) {
12897 SourceLocation Loc = ValExpr->getExprLoc();
12898 ExprResult Value =
12899 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
12900 if (Value.isInvalid())
12901 return false;
12902
12903 ValExpr = Value.get();
12904 // The expression must evaluate to a non-negative integer value.
12905 if (Optional<llvm::APSInt> Result =
12906 ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
12907 if (Result->isSigned() &&
12908 !((!StrictlyPositive && Result->isNonNegative()) ||
12909 (StrictlyPositive && Result->isStrictlyPositive()))) {
12910 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
12911 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
12912 << ValExpr->getSourceRange();
12913 return false;
12914 }
12915 }
12916 if (!BuildCapture)
12917 return true;
12918 *CaptureRegion =
12919 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
12920 if (*CaptureRegion != OMPD_unknown &&
12921 !SemaRef.CurContext->isDependentContext()) {
12922 ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
12923 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12924 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
12925 *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
12926 }
12927 }
12928 return true;
12929}
12930
12931OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
12932 SourceLocation StartLoc,
12933 SourceLocation LParenLoc,
12934 SourceLocation EndLoc) {
12935 Expr *ValExpr = NumThreads;
12936 Stmt *HelperValStmt = nullptr;
12937
12938 // OpenMP [2.5, Restrictions]
12939 // The num_threads expression must evaluate to a positive integer value.
12940 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
12941 /*StrictlyPositive=*/true))
12942 return nullptr;
12943
12944 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12945 OpenMPDirectiveKind CaptureRegion =
12946 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
12947 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12948 ValExpr = MakeFullExpr(ValExpr).get();
12949 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12950 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12951 HelperValStmt = buildPreInits(Context, Captures);
12952 }
12953
12954 return new (Context) OMPNumThreadsClause(
12955 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
12956}
12957
12958ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
12959 OpenMPClauseKind CKind,
12960 bool StrictlyPositive) {
12961 if (!E)
12962 return ExprError();
12963 if (E->isValueDependent() || E->isTypeDependent() ||
12964 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
12965 return E;
12966 llvm::APSInt Result;
12967 ExprResult ICE =
12968 VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold);
12969 if (ICE.isInvalid())
12970 return ExprError();
12971 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
12972 (!StrictlyPositive && !Result.isNonNegative())) {
12973 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
12974 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
12975 << E->getSourceRange();
12976 return ExprError();
12977 }
12978 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
12979 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
12980 << E->getSourceRange();
12981 return ExprError();
12982 }
12983 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
12984 DSAStack->setAssociatedLoops(Result.getExtValue());
12985 else if (CKind == OMPC_ordered)
12986 DSAStack->setAssociatedLoops(Result.getExtValue());
12987 return ICE;
12988}
12989
12990OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
12991 SourceLocation LParenLoc,
12992 SourceLocation EndLoc) {
12993 // OpenMP [2.8.1, simd construct, Description]
12994 // The parameter of the safelen clause must be a constant
12995 // positive integer expression.
12996 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
12997 if (Safelen.isInvalid())
12998 return nullptr;
12999 return new (Context)
13000 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
13001}
13002
13003OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
13004 SourceLocation LParenLoc,
13005 SourceLocation EndLoc) {
13006 // OpenMP [2.8.1, simd construct, Description]
13007 // The parameter of the simdlen clause must be a constant
13008 // positive integer expression.
13009 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
13010 if (Simdlen.isInvalid())
13011 return nullptr;
13012 return new (Context)
13013 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
13014}
13015
13016/// Tries to find omp_allocator_handle_t type.
13017static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
13018 DSAStackTy *Stack) {
13019 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
13020 if (!OMPAllocatorHandleT.isNull())
13021 return true;
13022 // Build the predefined allocator expressions.
13023 bool ErrorFound = false;
13024 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
13025 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
13026 StringRef Allocator =
13027 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
13028 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
13029 auto *VD = dyn_cast_or_null<ValueDecl>(
13030 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
13031 if (!VD) {
13032 ErrorFound = true;
13033 break;
13034 }
13035 QualType AllocatorType =
13036 VD->getType().getNonLValueExprType(S.getASTContext());
13037 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
13038 if (!Res.isUsable()) {
13039 ErrorFound = true;
13040 break;
13041 }
13042 if (OMPAllocatorHandleT.isNull())
13043 OMPAllocatorHandleT = AllocatorType;
13044 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
13045 ErrorFound = true;
13046 break;
13047 }
13048 Stack->setAllocator(AllocatorKind, Res.get());
13049 }
13050 if (ErrorFound) {
13051 S.Diag(Loc, diag::err_omp_implied_type_not_found)
13052 << "omp_allocator_handle_t";
13053 return false;
13054 }
13055 OMPAllocatorHandleT.addConst();
13056 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
13057 return true;
13058}
13059
13060OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
13061 SourceLocation LParenLoc,
13062 SourceLocation EndLoc) {
13063 // OpenMP [2.11.3, allocate Directive, Description]
13064 // allocator is an expression of omp_allocator_handle_t type.
13065 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
13066 return nullptr;
13067
13068 ExprResult Allocator = DefaultLvalueConversion(A);
13069 if (Allocator.isInvalid())
13070 return nullptr;
13071 Allocator = PerformImplicitConversion(Allocator.get(),
13072 DSAStack->getOMPAllocatorHandleT(),
13073 Sema::AA_Initializing,
13074 /*AllowExplicit=*/true);
13075 if (Allocator.isInvalid())
13076 return nullptr;
13077 return new (Context)
13078 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
13079}
13080
13081OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
13082 SourceLocation StartLoc,
13083 SourceLocation LParenLoc,
13084 SourceLocation EndLoc) {
13085 // OpenMP [2.7.1, loop construct, Description]
13086 // OpenMP [2.8.1, simd construct, Description]
13087 // OpenMP [2.9.6, distribute construct, Description]
13088 // The parameter of the collapse clause must be a constant
13089 // positive integer expression.
13090 ExprResult NumForLoopsResult =
13091 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
13092 if (NumForLoopsResult.isInvalid())
13093 return nullptr;
13094 return new (Context)
13095 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
13096}
13097
13098OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
13099 SourceLocation EndLoc,
13100 SourceLocation LParenLoc,
13101 Expr *NumForLoops) {
13102 // OpenMP [2.7.1, loop construct, Description]
13103 // OpenMP [2.8.1, simd construct, Description]
13104 // OpenMP [2.9.6, distribute construct, Description]
13105 // The parameter of the ordered clause must be a constant
13106 // positive integer expression if any.
13107 if (NumForLoops && LParenLoc.isValid()) {
13108 ExprResult NumForLoopsResult =
13109 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
13110 if (NumForLoopsResult.isInvalid())
13111 return nullptr;
13112 NumForLoops = NumForLoopsResult.get();
13113 } else {
13114 NumForLoops = nullptr;
13115 }
13116 auto *Clause = OMPOrderedClause::Create(
13117 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
13118 StartLoc, LParenLoc, EndLoc);
13119 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
13120 return Clause;
13121}
13122
13123OMPClause *Sema::ActOnOpenMPSimpleClause(
13124 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
13125 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
13126 OMPClause *Res = nullptr;
13127 switch (Kind) {
13128 case OMPC_default:
13129 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
13130 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13131 break;
13132 case OMPC_proc_bind:
13133 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
13134 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13135 break;
13136 case OMPC_atomic_default_mem_order:
13137 Res = ActOnOpenMPAtomicDefaultMemOrderClause(
13138 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
13139 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13140 break;
13141 case OMPC_order:
13142 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument),
13143 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13144 break;
13145 case OMPC_update:
13146 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
13147 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13148 break;
13149 case OMPC_if:
13150 case OMPC_final:
13151 case OMPC_num_threads:
13152 case OMPC_safelen:
13153 case OMPC_simdlen:
13154 case OMPC_allocator:
13155 case OMPC_collapse:
13156 case OMPC_schedule:
13157 case OMPC_private:
13158 case OMPC_firstprivate:
13159 case OMPC_lastprivate:
13160 case OMPC_shared:
13161 case OMPC_reduction:
13162 case OMPC_task_reduction:
13163 case OMPC_in_reduction:
13164 case OMPC_linear:
13165 case OMPC_aligned:
13166 case OMPC_copyin:
13167 case OMPC_copyprivate:
13168 case OMPC_ordered:
13169 case OMPC_nowait:
13170 case OMPC_untied:
13171 case OMPC_mergeable:
13172 case OMPC_threadprivate:
13173 case OMPC_allocate:
13174 case OMPC_flush:
13175 case OMPC_depobj:
13176 case OMPC_read:
13177 case OMPC_write:
13178 case OMPC_capture:
13179 case OMPC_seq_cst:
13180 case OMPC_acq_rel:
13181 case OMPC_acquire:
13182 case OMPC_release:
13183 case OMPC_relaxed:
13184 case OMPC_depend:
13185 case OMPC_device:
13186 case OMPC_threads:
13187 case OMPC_simd:
13188 case OMPC_map:
13189 case OMPC_num_teams:
13190 case OMPC_thread_limit:
13191 case OMPC_priority:
13192 case OMPC_grainsize:
13193 case OMPC_nogroup:
13194 case OMPC_num_tasks:
13195 case OMPC_hint:
13196 case OMPC_dist_schedule:
13197 case OMPC_defaultmap:
13198 case OMPC_unknown:
13199 case OMPC_uniform:
13200 case OMPC_to:
13201 case OMPC_from:
13202 case OMPC_use_device_ptr:
13203 case OMPC_use_device_addr:
13204 case OMPC_is_device_ptr:
13205 case OMPC_unified_address:
13206 case OMPC_unified_shared_memory:
13207 case OMPC_reverse_offload:
13208 case OMPC_dynamic_allocators:
13209 case OMPC_device_type:
13210 case OMPC_match:
13211 case OMPC_nontemporal:
13212 case OMPC_destroy:
13213 case OMPC_detach:
13214 case OMPC_inclusive:
13215 case OMPC_exclusive:
13216 case OMPC_uses_allocators:
13217 case OMPC_affinity:
13218 default:
13219 llvm_unreachable("Clause is not allowed.");
13220 }
13221 return Res;
13222}
13223
13224static std::string
13225getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
13226 ArrayRef<unsigned> Exclude = llvm::None) {
13227 SmallString<256> Buffer;
13228 llvm::raw_svector_ostream Out(Buffer);
13229 unsigned Skipped = Exclude.size();
13230 auto S = Exclude.begin(), E = Exclude.end();
13231 for (unsigned I = First; I < Last; ++I) {
13232 if (std::find(S, E, I) != E) {
13233 --Skipped;
13234 continue;
13235 }
13236 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
13237 if (I + Skipped + 2 == Last)
13238 Out << " or ";
13239 else if (I + Skipped + 1 != Last)
13240 Out << ", ";
13241 }
13242 return std::string(Out.str());
13243}
13244
13245OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
13246 SourceLocation KindKwLoc,
13247 SourceLocation StartLoc,
13248 SourceLocation LParenLoc,
13249 SourceLocation EndLoc) {
13250 if (Kind == OMP_DEFAULT_unknown) {
13251 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13252 << getListOfPossibleValues(OMPC_default, /*First=*/0,
13253 /*Last=*/unsigned(OMP_DEFAULT_unknown))
13254 << getOpenMPClauseName(OMPC_default);
13255 return nullptr;
13256 }
13257
13258 switch (Kind) {
13259 case OMP_DEFAULT_none:
13260 DSAStack->setDefaultDSANone(KindKwLoc);
13261 break;
13262 case OMP_DEFAULT_shared:
13263 DSAStack->setDefaultDSAShared(KindKwLoc);
13264 break;
13265 case OMP_DEFAULT_firstprivate:
13266 DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
13267 break;
13268 default:
13269 llvm_unreachable("DSA unexpected in OpenMP default clause");
13270 }
13271
13272 return new (Context)
13273 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13274}
13275
13276OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
13277 SourceLocation KindKwLoc,
13278 SourceLocation StartLoc,
13279 SourceLocation LParenLoc,
13280 SourceLocation EndLoc) {
13281 if (Kind == OMP_PROC_BIND_unknown) {
13282 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13283 << getListOfPossibleValues(OMPC_proc_bind,
13284 /*First=*/unsigned(OMP_PROC_BIND_master),
13285 /*Last=*/5)
13286 << getOpenMPClauseName(OMPC_proc_bind);
13287 return nullptr;
13288 }
13289 return new (Context)
13290 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13291}
13292
13293OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
13294 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
13295 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
13296 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
13297 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13298 << getListOfPossibleValues(
13299 OMPC_atomic_default_mem_order, /*First=*/0,
13300 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
13301 << getOpenMPClauseName(OMPC_atomic_default_mem_order);
13302 return nullptr;
13303 }
13304 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
13305 LParenLoc, EndLoc);
13306}
13307
13308OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
13309 SourceLocation KindKwLoc,
13310 SourceLocation StartLoc,
13311 SourceLocation LParenLoc,
13312 SourceLocation EndLoc) {
13313 if (Kind == OMPC_ORDER_unknown) {
13314 static_assert(OMPC_ORDER_unknown > 0,
13315 "OMPC_ORDER_unknown not greater than 0");
13316 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13317 << getListOfPossibleValues(OMPC_order, /*First=*/0,
13318 /*Last=*/OMPC_ORDER_unknown)
13319 << getOpenMPClauseName(OMPC_order);
13320 return nullptr;
13321 }
13322 return new (Context)
13323 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13324}
13325
13326OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
13327 SourceLocation KindKwLoc,
13328 SourceLocation StartLoc,
13329 SourceLocation LParenLoc,
13330 SourceLocation EndLoc) {
13331 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
13332 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
13333 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
13334 OMPC_DEPEND_depobj};
13335 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13336 << getListOfPossibleValues(OMPC_depend, /*First=*/0,
13337 /*Last=*/OMPC_DEPEND_unknown, Except)
13338 << getOpenMPClauseName(OMPC_update);
13339 return nullptr;
13340 }
13341 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
13342 EndLoc);
13343}
13344
13345OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
13346 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
13347 SourceLocation StartLoc, SourceLocation LParenLoc,
13348 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
13349 SourceLocation EndLoc) {
13350 OMPClause *Res = nullptr;
13351 switch (Kind) {
13352 case OMPC_schedule:
13353 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
13354 assert(Argument.size() == NumberOfElements &&
13355 ArgumentLoc.size() == NumberOfElements);
13356 Res = ActOnOpenMPScheduleClause(
13357 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
13358 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
13359 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
13360 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
13361 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
13362 break;
13363 case OMPC_if:
13364 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
13365 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
13366 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
13367 DelimLoc, EndLoc);
13368 break;
13369 case OMPC_dist_schedule:
13370 Res = ActOnOpenMPDistScheduleClause(
13371 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
13372 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
13373 break;
13374 case OMPC_defaultmap:
13375 enum { Modifier, DefaultmapKind };
13376 Res = ActOnOpenMPDefaultmapClause(
13377 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
13378 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
13379 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
13380 EndLoc);
13381 break;
13382 case OMPC_device:
13383 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
13384 Res = ActOnOpenMPDeviceClause(
13385 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
13386 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
13387 break;
13388 case OMPC_final:
13389 case OMPC_num_threads:
13390 case OMPC_safelen:
13391 case OMPC_simdlen:
13392 case OMPC_allocator:
13393 case OMPC_collapse:
13394 case OMPC_default:
13395 case OMPC_proc_bind:
13396 case OMPC_private:
13397 case OMPC_firstprivate:
13398 case OMPC_lastprivate:
13399 case OMPC_shared:
13400 case OMPC_reduction:
13401 case OMPC_task_reduction:
13402 case OMPC_in_reduction:
13403 case OMPC_linear:
13404 case OMPC_aligned:
13405 case OMPC_copyin:
13406 case OMPC_copyprivate:
13407 case OMPC_ordered:
13408 case OMPC_nowait:
13409 case OMPC_untied:
13410 case OMPC_mergeable:
13411 case OMPC_threadprivate:
13412 case OMPC_allocate:
13413 case OMPC_flush:
13414 case OMPC_depobj:
13415 case OMPC_read:
13416 case OMPC_write:
13417 case OMPC_update:
13418 case OMPC_capture:
13419 case OMPC_seq_cst:
13420 case OMPC_acq_rel:
13421 case OMPC_acquire:
13422 case OMPC_release:
13423 case OMPC_relaxed:
13424 case OMPC_depend:
13425 case OMPC_threads:
13426 case OMPC_simd:
13427 case OMPC_map:
13428 case OMPC_num_teams:
13429 case OMPC_thread_limit:
13430 case OMPC_priority:
13431 case OMPC_grainsize:
13432 case OMPC_nogroup:
13433 case OMPC_num_tasks:
13434 case OMPC_hint:
13435 case OMPC_unknown:
13436 case OMPC_uniform:
13437 case OMPC_to:
13438 case OMPC_from:
13439 case OMPC_use_device_ptr:
13440 case OMPC_use_device_addr:
13441 case OMPC_is_device_ptr:
13442 case OMPC_unified_address:
13443 case OMPC_unified_shared_memory:
13444 case OMPC_reverse_offload:
13445 case OMPC_dynamic_allocators:
13446 case OMPC_atomic_default_mem_order:
13447 case OMPC_device_type:
13448 case OMPC_match:
13449 case OMPC_nontemporal:
13450 case OMPC_order:
13451 case OMPC_destroy:
13452 case OMPC_detach:
13453 case OMPC_inclusive:
13454 case OMPC_exclusive:
13455 case OMPC_uses_allocators:
13456 case OMPC_affinity:
13457 default:
13458 llvm_unreachable("Clause is not allowed.");
13459 }
13460 return Res;
13461}
13462
13463static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
13464 OpenMPScheduleClauseModifier M2,
13465 SourceLocation M1Loc, SourceLocation M2Loc) {
13466 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
13467 SmallVector<unsigned, 2> Excluded;
13468 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
13469 Excluded.push_back(M2);
13470 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
13471 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
13472 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
13473 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
13474 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
13475 << getListOfPossibleValues(OMPC_schedule,
13476 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
13477 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
13478 Excluded)
13479 << getOpenMPClauseName(OMPC_schedule);
13480 return true;
13481 }
13482 return false;
13483}
13484
13485OMPClause *Sema::ActOnOpenMPScheduleClause(
13486 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
13487 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
13488 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
13489 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
13490 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
13491 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
13492 return nullptr;
13493 // OpenMP, 2.7.1, Loop Construct, Restrictions
13494 // Either the monotonic modifier or the nonmonotonic modifier can be specified
13495 // but not both.
13496 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
13497 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
13498 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
13499 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
13500 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
13501 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
13502 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
13503 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
13504 return nullptr;
13505 }
13506 if (Kind == OMPC_SCHEDULE_unknown) {
13507 std::string Values;
13508 if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
13509 unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
13510 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
13511 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
13512 Exclude);
13513 } else {
13514 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
13515 /*Last=*/OMPC_SCHEDULE_unknown);
13516 }
13517 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
13518 << Values << getOpenMPClauseName(OMPC_schedule);
13519 return nullptr;
13520 }
13521 // OpenMP, 2.7.1, Loop Construct, Restrictions
13522 // The nonmonotonic modifier can only be specified with schedule(dynamic) or
13523 // schedule(guided).
13524 // OpenMP 5.0 does not have this restriction.
13525 if (LangOpts.OpenMP < 50 &&
13526 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
13527 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
13528 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
13529 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
13530 diag::err_omp_schedule_nonmonotonic_static);
13531 return nullptr;
13532 }
13533 Expr *ValExpr = ChunkSize;
13534 Stmt *HelperValStmt = nullptr;
13535 if (ChunkSize) {
13536 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
13537 !ChunkSize->isInstantiationDependent() &&
13538 !ChunkSize->containsUnexpandedParameterPack()) {
13539 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
13540 ExprResult Val =
13541 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
13542 if (Val.isInvalid())
13543 return nullptr;
13544
13545 ValExpr = Val.get();
13546
13547 // OpenMP [2.7.1, Restrictions]
13548 // chunk_size must be a loop invariant integer expression with a positive
13549 // value.
13550 if (Optional<llvm::APSInt> Result =
13551 ValExpr->getIntegerConstantExpr(Context)) {
13552 if (Result->isSigned() && !Result->isStrictlyPositive()) {
13553 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
13554 << "schedule" << 1 << ChunkSize->getSourceRange();
13555 return nullptr;
13556 }
13557 } else if (getOpenMPCaptureRegionForClause(
13558 DSAStack->getCurrentDirective(), OMPC_schedule,
13559 LangOpts.OpenMP) != OMPD_unknown &&
13560 !CurContext->isDependentContext()) {
13561 ValExpr = MakeFullExpr(ValExpr).get();
13562 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13563 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13564 HelperValStmt = buildPreInits(Context, Captures);
13565 }
13566 }
13567 }
13568
13569 return new (Context)
13570 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
13571 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
13572}
13573
13574OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
13575 SourceLocation StartLoc,
13576 SourceLocation EndLoc) {
13577 OMPClause *Res = nullptr;
13578 switch (Kind) {
13579 case OMPC_ordered:
13580 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
13581 break;
13582 case OMPC_nowait:
13583 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
13584 break;
13585 case OMPC_untied:
13586 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
13587 break;
13588 case OMPC_mergeable:
13589 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
13590 break;
13591 case OMPC_read:
13592 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
13593 break;
13594 case OMPC_write:
13595 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
13596 break;
13597 case OMPC_update:
13598 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
13599 break;
13600 case OMPC_capture:
13601 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
13602 break;
13603 case OMPC_seq_cst:
13604 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
13605 break;
13606 case OMPC_acq_rel:
13607 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
13608 break;
13609 case OMPC_acquire:
13610 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
13611 break;
13612 case OMPC_release:
13613 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
13614 break;
13615 case OMPC_relaxed:
13616 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
13617 break;
13618 case OMPC_threads:
13619 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
13620 break;
13621 case OMPC_simd:
13622 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
13623 break;
13624 case OMPC_nogroup:
13625 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
13626 break;
13627 case OMPC_unified_address:
13628 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
13629 break;
13630 case OMPC_unified_shared_memory:
13631 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
13632 break;
13633 case OMPC_reverse_offload:
13634 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
13635 break;
13636 case OMPC_dynamic_allocators:
13637 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
13638 break;
13639 case OMPC_destroy:
13640 Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc);
13641 break;
13642 case OMPC_if:
13643 case OMPC_final:
13644 case OMPC_num_threads:
13645 case OMPC_safelen:
13646 case OMPC_simdlen:
13647 case OMPC_allocator:
13648 case OMPC_collapse:
13649 case OMPC_schedule:
13650 case OMPC_private:
13651 case OMPC_firstprivate:
13652 case OMPC_lastprivate:
13653 case OMPC_shared:
13654 case OMPC_reduction:
13655 case OMPC_task_reduction:
13656 case OMPC_in_reduction:
13657 case OMPC_linear:
13658 case OMPC_aligned:
13659 case OMPC_copyin:
13660 case OMPC_copyprivate:
13661 case OMPC_default:
13662 case OMPC_proc_bind:
13663 case OMPC_threadprivate:
13664 case OMPC_allocate:
13665 case OMPC_flush:
13666 case OMPC_depobj:
13667 case OMPC_depend:
13668 case OMPC_device:
13669 case OMPC_map:
13670 case OMPC_num_teams:
13671 case OMPC_thread_limit:
13672 case OMPC_priority:
13673 case OMPC_grainsize:
13674 case OMPC_num_tasks:
13675 case OMPC_hint:
13676 case OMPC_dist_schedule:
13677 case OMPC_defaultmap:
13678 case OMPC_unknown:
13679 case OMPC_uniform:
13680 case OMPC_to:
13681 case OMPC_from:
13682 case OMPC_use_device_ptr:
13683 case OMPC_use_device_addr:
13684 case OMPC_is_device_ptr:
13685 case OMPC_atomic_default_mem_order:
13686 case OMPC_device_type:
13687 case OMPC_match:
13688 case OMPC_nontemporal:
13689 case OMPC_order:
13690 case OMPC_detach:
13691 case OMPC_inclusive:
13692 case OMPC_exclusive:
13693 case OMPC_uses_allocators:
13694 case OMPC_affinity:
13695 default:
13696 llvm_unreachable("Clause is not allowed.");
13697 }
13698 return Res;
13699}
13700
13701OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
13702 SourceLocation EndLoc) {
13703 DSAStack->setNowaitRegion();
13704 return new (Context) OMPNowaitClause(StartLoc, EndLoc);
13705}
13706
13707OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
13708 SourceLocation EndLoc) {
13709 return new (Context) OMPUntiedClause(StartLoc, EndLoc);
13710}
13711
13712OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
13713 SourceLocation EndLoc) {
13714 return new (Context) OMPMergeableClause(StartLoc, EndLoc);
13715}
13716
13717OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
13718 SourceLocation EndLoc) {
13719 return new (Context) OMPReadClause(StartLoc, EndLoc);
13720}
13721
13722OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
13723 SourceLocation EndLoc) {
13724 return new (Context) OMPWriteClause(StartLoc, EndLoc);
13725}
13726
13727OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
13728 SourceLocation EndLoc) {
13729 return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
13730}
13731
13732OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
13733 SourceLocation EndLoc) {
13734 return new (Context) OMPCaptureClause(StartLoc, EndLoc);
13735}
13736
13737OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
13738 SourceLocation EndLoc) {
13739 return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
13740}
13741
13742OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
13743 SourceLocation EndLoc) {
13744 return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
13745}
13746
13747OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
13748 SourceLocation EndLoc) {
13749 return new (Context) OMPAcquireClause(StartLoc, EndLoc);
13750}
13751
13752OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
13753 SourceLocation EndLoc) {
13754 return new (Context) OMPReleaseClause(StartLoc, EndLoc);
13755}
13756
13757OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
13758 SourceLocation EndLoc) {
13759 return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
13760}
13761
13762OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
13763 SourceLocation EndLoc) {
13764 return new (Context) OMPThreadsClause(StartLoc, EndLoc);
13765}
13766
13767OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
13768 SourceLocation EndLoc) {
13769 return new (Context) OMPSIMDClause(StartLoc, EndLoc);
13770}
13771
13772OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
13773 SourceLocation EndLoc) {
13774 return new (Context) OMPNogroupClause(StartLoc, EndLoc);
13775}
13776
13777OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
13778 SourceLocation EndLoc) {
13779 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
13780}
13781
13782OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
13783 SourceLocation EndLoc) {
13784 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
13785}
13786
13787OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
13788 SourceLocation EndLoc) {
13789 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
13790}
13791
13792OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
13793 SourceLocation EndLoc) {
13794 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
13795}
13796
13797OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc,
13798 SourceLocation EndLoc) {
13799 return new (Context) OMPDestroyClause(StartLoc, EndLoc);
13800}
13801
13802OMPClause *Sema::ActOnOpenMPVarListClause(
13803 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr,
13804 const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
13805 CXXScopeSpec &ReductionOrMapperIdScopeSpec,
13806 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier,
13807 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
13808 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit,
13809 SourceLocation ExtraModifierLoc,
13810 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
13811 ArrayRef<SourceLocation> MotionModifiersLoc) {
13812 SourceLocation StartLoc = Locs.StartLoc;
13813 SourceLocation LParenLoc = Locs.LParenLoc;
13814 SourceLocation EndLoc = Locs.EndLoc;
13815 OMPClause *Res = nullptr;
13816 switch (Kind) {
13817 case OMPC_private:
13818 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13819 break;
13820 case OMPC_firstprivate:
13821 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13822 break;
13823 case OMPC_lastprivate:
13824 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&
13825 "Unexpected lastprivate modifier.");
13826 Res = ActOnOpenMPLastprivateClause(
13827 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
13828 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
13829 break;
13830 case OMPC_shared:
13831 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
13832 break;
13833 case OMPC_reduction:
13834 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&
13835 "Unexpected lastprivate modifier.");
13836 Res = ActOnOpenMPReductionClause(
13837 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
13838 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
13839 ReductionOrMapperIdScopeSpec, ReductionOrMapperId);
13840 break;
13841 case OMPC_task_reduction:
13842 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
13843 EndLoc, ReductionOrMapperIdScopeSpec,
13844 ReductionOrMapperId);
13845 break;
13846 case OMPC_in_reduction:
13847 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
13848 EndLoc, ReductionOrMapperIdScopeSpec,
13849 ReductionOrMapperId);
13850 break;
13851 case OMPC_linear:
13852 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&
13853 "Unexpected linear modifier.");
13854 Res = ActOnOpenMPLinearClause(
13855 VarList, DepModOrTailExpr, StartLoc, LParenLoc,
13856 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
13857 ColonLoc, EndLoc);
13858 break;
13859 case OMPC_aligned:
13860 Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc,
13861 LParenLoc, ColonLoc, EndLoc);
13862 break;
13863 case OMPC_copyin:
13864 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
13865 break;
13866 case OMPC_copyprivate:
13867 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13868 break;
13869 case OMPC_flush:
13870 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
13871 break;
13872 case OMPC_depend:
13873 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&
13874 "Unexpected depend modifier.");
13875 Res = ActOnOpenMPDependClause(
13876 DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier),
13877 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
13878 break;
13879 case OMPC_map:
13880 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&
13881 "Unexpected map modifier.");
13882 Res = ActOnOpenMPMapClause(
13883 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec,
13884 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier),
13885 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs);
13886 break;
13887 case OMPC_to:
13888 Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc,
13889 ReductionOrMapperIdScopeSpec, ReductionOrMapperId,
13890 ColonLoc, VarList, Locs);
13891 break;
13892 case OMPC_from:
13893 Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc,
13894 ReductionOrMapperIdScopeSpec,
13895 ReductionOrMapperId, ColonLoc, VarList, Locs);
13896 break;
13897 case OMPC_use_device_ptr:
13898 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
13899 break;
13900 case OMPC_use_device_addr:
13901 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
13902 break;
13903 case OMPC_is_device_ptr:
13904 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
13905 break;
13906 case OMPC_allocate:
13907 Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc,
13908 LParenLoc, ColonLoc, EndLoc);
13909 break;
13910 case OMPC_nontemporal:
13911 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
13912 break;
13913 case OMPC_inclusive:
13914 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
13915 break;
13916 case OMPC_exclusive:
13917 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
13918 break;
13919 case OMPC_affinity:
13920 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
13921 DepModOrTailExpr, VarList);
13922 break;
13923 case OMPC_if:
13924 case OMPC_depobj:
13925 case OMPC_final:
13926 case OMPC_num_threads:
13927 case OMPC_safelen:
13928 case OMPC_simdlen:
13929 case OMPC_allocator:
13930 case OMPC_collapse:
13931 case OMPC_default:
13932 case OMPC_proc_bind:
13933 case OMPC_schedule:
13934 case OMPC_ordered:
13935 case OMPC_nowait:
13936 case OMPC_untied:
13937 case OMPC_mergeable:
13938 case OMPC_threadprivate:
13939 case OMPC_read:
13940 case OMPC_write:
13941 case OMPC_update:
13942 case OMPC_capture:
13943 case OMPC_seq_cst:
13944 case OMPC_acq_rel:
13945 case OMPC_acquire:
13946 case OMPC_release:
13947 case OMPC_relaxed:
13948 case OMPC_device:
13949 case OMPC_threads:
13950 case OMPC_simd:
13951 case OMPC_num_teams:
13952 case OMPC_thread_limit:
13953 case OMPC_priority:
13954 case OMPC_grainsize:
13955 case OMPC_nogroup:
13956 case OMPC_num_tasks:
13957 case OMPC_hint:
13958 case OMPC_dist_schedule:
13959 case OMPC_defaultmap:
13960 case OMPC_unknown:
13961 case OMPC_uniform:
13962 case OMPC_unified_address:
13963 case OMPC_unified_shared_memory:
13964 case OMPC_reverse_offload:
13965 case OMPC_dynamic_allocators:
13966 case OMPC_atomic_default_mem_order:
13967 case OMPC_device_type:
13968 case OMPC_match:
13969 case OMPC_order:
13970 case OMPC_destroy:
13971 case OMPC_detach:
13972 case OMPC_uses_allocators:
13973 default:
13974 llvm_unreachable("Clause is not allowed.");
13975 }
13976 return Res;
13977}
13978
13979ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
13980 ExprObjectKind OK, SourceLocation Loc) {
13981 ExprResult Res = BuildDeclRefExpr(
13982 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
13983 if (!Res.isUsable())
13984 return ExprError();
13985 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
13986 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
13987 if (!Res.isUsable())
13988 return ExprError();
13989 }
13990 if (VK != VK_LValue && Res.get()->isGLValue()) {
13991 Res = DefaultLvalueConversion(Res.get());
13992 if (!Res.isUsable())
13993 return ExprError();
13994 }
13995 return Res;
13996}
13997
13998OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
13999 SourceLocation StartLoc,
14000 SourceLocation LParenLoc,
14001 SourceLocation EndLoc) {
14002 SmallVector<Expr *, 8> Vars;
14003 SmallVector<Expr *, 8> PrivateCopies;
14004 for (Expr *RefExpr : VarList) {
14005 assert(RefExpr && "NULL expr in OpenMP private clause.");
14006 SourceLocation ELoc;
14007 SourceRange ERange;
14008 Expr *SimpleRefExpr = RefExpr;
14009 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14010 if (Res.second) {
14011 // It will be analyzed later.
14012 Vars.push_back(RefExpr);
14013 PrivateCopies.push_back(nullptr);
14014 }
14015 ValueDecl *D = Res.first;
14016 if (!D)
14017 continue;
14018
14019 QualType Type = D->getType();
14020 auto *VD = dyn_cast<VarDecl>(D);
14021
14022 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
14023 // A variable that appears in a private clause must not have an incomplete
14024 // type or a reference type.
14025 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
14026 continue;
14027 Type = Type.getNonReferenceType();
14028
14029 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
14030 // A variable that is privatized must not have a const-qualified type
14031 // unless it is of class type with a mutable member. This restriction does
14032 // not apply to the firstprivate clause.
14033 //
14034 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
14035 // A variable that appears in a private clause must not have a
14036 // const-qualified type unless it is of class type with a mutable member.
14037 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
14038 continue;
14039
14040 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14041 // in a Construct]
14042 // Variables with the predetermined data-sharing attributes may not be
14043 // listed in data-sharing attributes clauses, except for the cases
14044 // listed below. For these exceptions only, listing a predetermined
14045 // variable in a data-sharing attribute clause is allowed and overrides
14046 // the variable's predetermined data-sharing attributes.
14047 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
14048 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
14049 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
14050 << getOpenMPClauseName(OMPC_private);
14051 reportOriginalDsa(*this, DSAStack, D, DVar);
14052 continue;
14053 }
14054
14055 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
14056 // Variably modified types are not supported for tasks.
14057 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
14058 isOpenMPTaskingDirective(CurrDir)) {
14059 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
14060 << getOpenMPClauseName(OMPC_private) << Type
14061 << getOpenMPDirectiveName(CurrDir);
14062 bool IsDecl =
14063 !VD ||
14064 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
14065 Diag(D->getLocation(),
14066 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14067 << D;
14068 continue;
14069 }
14070
14071 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
14072 // A list item cannot appear in both a map clause and a data-sharing
14073 // attribute clause on the same construct
14074 //
14075 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
14076 // A list item cannot appear in both a map clause and a data-sharing
14077 // attribute clause on the same construct unless the construct is a
14078 // combined construct.
14079 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
14080 CurrDir == OMPD_target) {
14081 OpenMPClauseKind ConflictKind;
14082 if (DSAStack->checkMappableExprComponentListsForDecl(
14083 VD, /*CurrentRegionOnly=*/true,
14084 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
14085 OpenMPClauseKind WhereFoundClauseKind) -> bool {
14086 ConflictKind = WhereFoundClauseKind;
14087 return true;
14088 })) {
14089 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
14090 << getOpenMPClauseName(OMPC_private)
14091 << getOpenMPClauseName(ConflictKind)
14092 << getOpenMPDirectiveName(CurrDir);
14093 reportOriginalDsa(*this, DSAStack, D, DVar);
14094 continue;
14095 }
14096 }
14097
14098 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
14099 // A variable of class type (or array thereof) that appears in a private
14100 // clause requires an accessible, unambiguous default constructor for the
14101 // class type.
14102 // Generate helper private variable and initialize it with the default
14103 // value. The address of the original variable is replaced by the address of
14104 // the new private variable in CodeGen. This new variable is not added to
14105 // IdResolver, so the code in the OpenMP region uses original variable for
14106 // proper diagnostics.
14107 Type = Type.getUnqualifiedType();
14108 VarDecl *VDPrivate =
14109 buildVarDecl(*this, ELoc, Type, D->getName(),
14110 D->hasAttrs() ? &D->getAttrs() : nullptr,
14111 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
14112 ActOnUninitializedDecl(VDPrivate);
14113 if (VDPrivate->isInvalidDecl())
14114 continue;
14115 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
14116 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
14117
14118 DeclRefExpr *Ref = nullptr;
14119 if (!VD && !CurContext->isDependentContext())
14120 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
14121 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
14122 Vars.push_back((VD || CurContext->isDependentContext())
14123 ? RefExpr->IgnoreParens()
14124 : Ref);
14125 PrivateCopies.push_back(VDPrivateRefExpr);
14126 }
14127
14128 if (Vars.empty())
14129 return nullptr;
14130
14131 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
14132 PrivateCopies);
14133}
14134
14135namespace {
14136class DiagsUninitializedSeveretyRAII {
14137private:
14138 DiagnosticsEngine &Diags;
14139 SourceLocation SavedLoc;
14140 bool IsIgnored = false;
14141
14142public:
14143 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
14144 bool IsIgnored)
14145 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
14146 if (!IsIgnored) {
14147 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
14148 /*Map*/ diag::Severity::Ignored, Loc);
14149 }
14150 }
14151 ~DiagsUninitializedSeveretyRAII() {
14152 if (!IsIgnored)
14153 Diags.popMappings(SavedLoc);
14154 }
14155};
14156}
14157
14158OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
14159 SourceLocation StartLoc,
14160 SourceLocation LParenLoc,
14161 SourceLocation EndLoc) {
14162 SmallVector<Expr *, 8> Vars;
14163 SmallVector<Expr *, 8> PrivateCopies;
14164 SmallVector<Expr *, 8> Inits;
14165 SmallVector<Decl *, 4> ExprCaptures;
14166 bool IsImplicitClause =
14167 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
14168 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
14169
14170 for (Expr *RefExpr : VarList) {
14171 assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
14172 SourceLocation ELoc;
14173 SourceRange ERange;
14174 Expr *SimpleRefExpr = RefExpr;
14175 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14176 if (Res.second) {
14177 // It will be analyzed later.
14178 Vars.push_back(RefExpr);
14179 PrivateCopies.push_back(nullptr);
14180 Inits.push_back(nullptr);
14181 }
14182 ValueDecl *D = Res.first;
14183 if (!D)
14184 continue;
14185
14186 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
14187 QualType Type = D->getType();
14188 auto *VD = dyn_cast<VarDecl>(D);
14189
14190 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
14191 // A variable that appears in a private clause must not have an incomplete
14192 // type or a reference type.
14193 if (RequireCompleteType(ELoc, Type,
14194 diag::err_omp_firstprivate_incomplete_type))
14195 continue;
14196 Type = Type.getNonReferenceType();
14197
14198 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
14199 // A variable of class type (or array thereof) that appears in a private
14200 // clause requires an accessible, unambiguous copy constructor for the
14201 // class type.
14202 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
14203
14204 // If an implicit firstprivate variable found it was checked already.
14205 DSAStackTy::DSAVarData TopDVar;
14206 if (!IsImplicitClause) {
14207 DSAStackTy::DSAVarData DVar =
14208 DSAStack->getTopDSA(D, /*FromParent=*/false);
14209 TopDVar = DVar;
14210 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
14211 bool IsConstant = ElemType.isConstant(Context);
14212 // OpenMP [2.4.13, Data-sharing Attribute Clauses]
14213 // A list item that specifies a given variable may not appear in more
14214 // than one clause on the same directive, except that a variable may be
14215 // specified in both firstprivate and lastprivate clauses.
14216 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
14217 // A list item may appear in a firstprivate or lastprivate clause but not
14218 // both.
14219 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
14220 (isOpenMPDistributeDirective(CurrDir) ||
14221 DVar.CKind != OMPC_lastprivate) &&
14222 DVar.RefExpr) {
14223 Diag(ELoc, diag::err_omp_wrong_dsa)
14224 << getOpenMPClauseName(DVar.CKind)
14225 << getOpenMPClauseName(OMPC_firstprivate);
14226 reportOriginalDsa(*this, DSAStack, D, DVar);
14227 continue;
14228 }
14229
14230 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14231 // in a Construct]
14232 // Variables with the predetermined data-sharing attributes may not be
14233 // listed in data-sharing attributes clauses, except for the cases
14234 // listed below. For these exceptions only, listing a predetermined
14235 // variable in a data-sharing attribute clause is allowed and overrides
14236 // the variable's predetermined data-sharing attributes.
14237 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14238 // in a Construct, C/C++, p.2]
14239 // Variables with const-qualified type having no mutable member may be
14240 // listed in a firstprivate clause, even if they are static data members.
14241 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
14242 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
14243 Diag(ELoc, diag::err_omp_wrong_dsa)
14244 << getOpenMPClauseName(DVar.CKind)
14245 << getOpenMPClauseName(OMPC_firstprivate);
14246 reportOriginalDsa(*this, DSAStack, D, DVar);
14247 continue;
14248 }
14249
14250 // OpenMP [2.9.3.4, Restrictions, p.2]
14251 // A list item that is private within a parallel region must not appear
14252 // in a firstprivate clause on a worksharing construct if any of the
14253 // worksharing regions arising from the worksharing construct ever bind
14254 // to any of the parallel regions arising from the parallel construct.
14255 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
14256 // A list item that is private within a teams region must not appear in a
14257 // firstprivate clause on a distribute construct if any of the distribute
14258 // regions arising from the distribute construct ever bind to any of the
14259 // teams regions arising from the teams construct.
14260 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
14261 // A list item that appears in a reduction clause of a teams construct
14262 // must not appear in a firstprivate clause on a distribute construct if
14263 // any of the distribute regions arising from the distribute construct
14264 // ever bind to any of the teams regions arising from the teams construct.
14265 if ((isOpenMPWorksharingDirective(CurrDir) ||
14266 isOpenMPDistributeDirective(CurrDir)) &&
14267 !isOpenMPParallelDirective(CurrDir) &&
14268 !isOpenMPTeamsDirective(CurrDir)) {
14269 DVar = DSAStack->getImplicitDSA(D, true);
14270 if (DVar.CKind != OMPC_shared &&
14271 (isOpenMPParallelDirective(DVar.DKind) ||
14272 isOpenMPTeamsDirective(DVar.DKind) ||
14273 DVar.DKind == OMPD_unknown)) {
14274 Diag(ELoc, diag::err_omp_required_access)
14275 << getOpenMPClauseName(OMPC_firstprivate)
14276 << getOpenMPClauseName(OMPC_shared);
14277 reportOriginalDsa(*this, DSAStack, D, DVar);
14278 continue;
14279 }
14280 }
14281 // OpenMP [2.9.3.4, Restrictions, p.3]
14282 // A list item that appears in a reduction clause of a parallel construct
14283 // must not appear in a firstprivate clause on a worksharing or task
14284 // construct if any of the worksharing or task regions arising from the
14285 // worksharing or task construct ever bind to any of the parallel regions
14286 // arising from the parallel construct.
14287 // OpenMP [2.9.3.4, Restrictions, p.4]
14288 // A list item that appears in a reduction clause in worksharing
14289 // construct must not appear in a firstprivate clause in a task construct
14290 // encountered during execution of any of the worksharing regions arising
14291 // from the worksharing construct.
14292 if (isOpenMPTaskingDirective(CurrDir)) {
14293 DVar = DSAStack->hasInnermostDSA(
14294 D,
14295 [](OpenMPClauseKind C, bool AppliedToPointee) {
14296 return C == OMPC_reduction && !AppliedToPointee;
14297 },
14298 [](OpenMPDirectiveKind K) {
14299 return isOpenMPParallelDirective(K) ||
14300 isOpenMPWorksharingDirective(K) ||
14301 isOpenMPTeamsDirective(K);
14302 },
14303 /*FromParent=*/true);
14304 if (DVar.CKind == OMPC_reduction &&
14305 (isOpenMPParallelDirective(DVar.DKind) ||
14306 isOpenMPWorksharingDirective(DVar.DKind) ||
14307 isOpenMPTeamsDirective(DVar.DKind))) {
14308 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
14309 << getOpenMPDirectiveName(DVar.DKind);
14310 reportOriginalDsa(*this, DSAStack, D, DVar);
14311 continue;
14312 }
14313 }
14314
14315 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
14316 // A list item cannot appear in both a map clause and a data-sharing
14317 // attribute clause on the same construct
14318 //
14319 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
14320 // A list item cannot appear in both a map clause and a data-sharing
14321 // attribute clause on the same construct unless the construct is a
14322 // combined construct.
14323 if ((LangOpts.OpenMP <= 45 &&
14324 isOpenMPTargetExecutionDirective(CurrDir)) ||
14325 CurrDir == OMPD_target) {
14326 OpenMPClauseKind ConflictKind;
14327 if (DSAStack->checkMappableExprComponentListsForDecl(
14328 VD, /*CurrentRegionOnly=*/true,
14329 [&ConflictKind](
14330 OMPClauseMappableExprCommon::MappableExprComponentListRef,
14331 OpenMPClauseKind WhereFoundClauseKind) {
14332 ConflictKind = WhereFoundClauseKind;
14333 return true;
14334 })) {
14335 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
14336 << getOpenMPClauseName(OMPC_firstprivate)
14337 << getOpenMPClauseName(ConflictKind)
14338 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
14339 reportOriginalDsa(*this, DSAStack, D, DVar);
14340 continue;
14341 }
14342 }
14343 }
14344
14345 // Variably modified types are not supported for tasks.
14346 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
14347 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
14348 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
14349 << getOpenMPClauseName(OMPC_firstprivate) << Type
14350 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
14351 bool IsDecl =
14352 !VD ||
14353 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
14354 Diag(D->getLocation(),
14355 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14356 << D;
14357 continue;
14358 }
14359
14360 Type = Type.getUnqualifiedType();
14361 VarDecl *VDPrivate =
14362 buildVarDecl(*this, ELoc, Type, D->getName(),
14363 D->hasAttrs() ? &D->getAttrs() : nullptr,
14364 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
14365 // Generate helper private variable and initialize it with the value of the
14366 // original variable. The address of the original variable is replaced by
14367 // the address of the new private variable in the CodeGen. This new variable
14368 // is not added to IdResolver, so the code in the OpenMP region uses
14369 // original variable for proper diagnostics and variable capturing.
14370 Expr *VDInitRefExpr = nullptr;
14371 // For arrays generate initializer for single element and replace it by the
14372 // original array element in CodeGen.
14373 if (Type->isArrayType()) {
14374 VarDecl *VDInit =
14375 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
14376 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
14377 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
14378 ElemType = ElemType.getUnqualifiedType();
14379 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
14380 ".firstprivate.temp");
14381 InitializedEntity Entity =
14382 InitializedEntity::InitializeVariable(VDInitTemp);
14383 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
14384
14385 InitializationSequence InitSeq(*this, Entity, Kind, Init);
14386 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
14387 if (Result.isInvalid())
14388 VDPrivate->setInvalidDecl();
14389 else
14390 VDPrivate->setInit(Result.getAs<Expr>());
14391 // Remove temp variable declaration.
14392 Context.Deallocate(VDInitTemp);
14393 } else {
14394 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
14395 ".firstprivate.temp");
14396 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
14397 RefExpr->getExprLoc());
14398 AddInitializerToDecl(VDPrivate,
14399 DefaultLvalueConversion(VDInitRefExpr).get(),
14400 /*DirectInit=*/false);
14401 }
14402 if (VDPrivate->isInvalidDecl()) {
14403 if (IsImplicitClause) {
14404 Diag(RefExpr->getExprLoc(),
14405 diag::note_omp_task_predetermined_firstprivate_here);
14406 }
14407 continue;
14408 }
14409 CurContext->addDecl(VDPrivate);
14410 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
14411 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
14412 RefExpr->getExprLoc());
14413 DeclRefExpr *Ref = nullptr;
14414 if (!VD && !CurContext->isDependentContext()) {
14415 if (TopDVar.CKind == OMPC_lastprivate) {
14416 Ref = TopDVar.PrivateCopy;
14417 } else {
14418 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
14419 if (!isOpenMPCapturedDecl(D))
14420 ExprCaptures.push_back(Ref->getDecl());
14421 }
14422 }
14423 if (!IsImplicitClause)
14424 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
14425 Vars.push_back((VD || CurContext->isDependentContext())
14426 ? RefExpr->IgnoreParens()
14427 : Ref);
14428 PrivateCopies.push_back(VDPrivateRefExpr);
14429 Inits.push_back(VDInitRefExpr);
14430 }
14431
14432 if (Vars.empty())
14433 return nullptr;
14434
14435 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14436 Vars, PrivateCopies, Inits,
14437 buildPreInits(Context, ExprCaptures));
14438}
14439
14440OMPClause *Sema::ActOnOpenMPLastprivateClause(
14441 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
14442 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
14443 SourceLocation LParenLoc, SourceLocation EndLoc) {
14444 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
14445 assert(ColonLoc.isValid() && "Colon location must be valid.");
14446 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
14447 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
14448 /*Last=*/OMPC_LASTPRIVATE_unknown)
14449 << getOpenMPClauseName(OMPC_lastprivate);
14450 return nullptr;
14451 }
14452
14453 SmallVector<Expr *, 8> Vars;
14454 SmallVector<Expr *, 8> SrcExprs;
14455 SmallVector<Expr *, 8> DstExprs;
14456 SmallVector<Expr *, 8> AssignmentOps;
14457 SmallVector<Decl *, 4> ExprCaptures;
14458 SmallVector<Expr *, 4> ExprPostUpdates;
14459 for (Expr *RefExpr : VarList) {
14460 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
14461 SourceLocation ELoc;
14462 SourceRange ERange;
14463 Expr *SimpleRefExpr = RefExpr;
14464 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14465 if (Res.second) {
14466 // It will be analyzed later.
14467 Vars.push_back(RefExpr);
14468 SrcExprs.push_back(nullptr);
14469 DstExprs.push_back(nullptr);
14470 AssignmentOps.push_back(nullptr);
14471 }
14472 ValueDecl *D = Res.first;
14473 if (!D)
14474 continue;
14475
14476 QualType Type = D->getType();
14477 auto *VD = dyn_cast<VarDecl>(D);
14478
14479 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
14480 // A variable that appears in a lastprivate clause must not have an
14481 // incomplete type or a reference type.
14482 if (RequireCompleteType(ELoc, Type,
14483 diag::err_omp_lastprivate_incomplete_type))
14484 continue;
14485 Type = Type.getNonReferenceType();
14486
14487 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
14488 // A variable that is privatized must not have a const-qualified type
14489 // unless it is of class type with a mutable member. This restriction does
14490 // not apply to the firstprivate clause.
14491 //
14492 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
14493 // A variable that appears in a lastprivate clause must not have a
14494 // const-qualified type unless it is of class type with a mutable member.
14495 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
14496 continue;
14497
14498 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
14499 // A list item that appears in a lastprivate clause with the conditional
14500 // modifier must be a scalar variable.
14501 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
14502 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
14503 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
14504 VarDecl::DeclarationOnly;
14505 Diag(D->getLocation(),
14506 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14507 << D;
14508 continue;
14509 }
14510
14511 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
14512 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
14513 // in a Construct]
14514 // Variables with the predetermined data-sharing attributes may not be
14515 // listed in data-sharing attributes clauses, except for the cases
14516 // listed below.
14517 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
14518 // A list item may appear in a firstprivate or lastprivate clause but not
14519 // both.
14520 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
14521 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
14522 (isOpenMPDistributeDirective(CurrDir) ||
14523 DVar.CKind != OMPC_firstprivate) &&
14524 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
14525 Diag(ELoc, diag::err_omp_wrong_dsa)
14526 << getOpenMPClauseName(DVar.CKind)
14527 << getOpenMPClauseName(OMPC_lastprivate);
14528 reportOriginalDsa(*this, DSAStack, D, DVar);
14529 continue;
14530 }
14531
14532 // OpenMP [2.14.3.5, Restrictions, p.2]
14533 // A list item that is private within a parallel region, or that appears in
14534 // the reduction clause of a parallel construct, must not appear in a
14535 // lastprivate clause on a worksharing construct if any of the corresponding
14536 // worksharing regions ever binds to any of the corresponding parallel
14537 // regions.
14538 DSAStackTy::DSAVarData TopDVar = DVar;
14539 if (isOpenMPWorksharingDirective(CurrDir) &&
14540 !isOpenMPParallelDirective(CurrDir) &&
14541 !isOpenMPTeamsDirective(CurrDir)) {
14542 DVar = DSAStack->getImplicitDSA(D, true);
14543 if (DVar.CKind != OMPC_shared) {
14544 Diag(ELoc, diag::err_omp_required_access)
14545 << getOpenMPClauseName(OMPC_lastprivate)
14546 << getOpenMPClauseName(OMPC_shared);
14547 reportOriginalDsa(*this, DSAStack, D, DVar);
14548 continue;
14549 }
14550 }
14551
14552 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
14553 // A variable of class type (or array thereof) that appears in a
14554 // lastprivate clause requires an accessible, unambiguous default
14555 // constructor for the class type, unless the list item is also specified
14556 // in a firstprivate clause.
14557 // A variable of class type (or array thereof) that appears in a
14558 // lastprivate clause requires an accessible, unambiguous copy assignment
14559 // operator for the class type.
14560 Type = Context.getBaseElementType(Type).getNonReferenceType();
14561 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
14562 Type.getUnqualifiedType(), ".lastprivate.src",
14563 D->hasAttrs() ? &D->getAttrs() : nullptr);
14564 DeclRefExpr *PseudoSrcExpr =
14565 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
14566 VarDecl *DstVD =
14567 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
14568 D->hasAttrs() ? &D->getAttrs() : nullptr);
14569 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
14570 // For arrays generate assignment operation for single element and replace
14571 // it by the original array element in CodeGen.
14572 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
14573 PseudoDstExpr, PseudoSrcExpr);
14574 if (AssignmentOp.isInvalid())
14575 continue;
14576 AssignmentOp =
14577 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
14578 if (AssignmentOp.isInvalid())
14579 continue;
14580
14581 DeclRefExpr *Ref = nullptr;
14582 if (!VD && !CurContext->isDependentContext()) {
14583 if (TopDVar.CKind == OMPC_firstprivate) {
14584 Ref = TopDVar.PrivateCopy;
14585 } else {
14586 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
14587 if (!isOpenMPCapturedDecl(D))
14588 ExprCaptures.push_back(Ref->getDecl());
14589 }
14590 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
14591 (!isOpenMPCapturedDecl(D) &&
14592 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
14593 ExprResult RefRes = DefaultLvalueConversion(Ref);
14594 if (!RefRes.isUsable())
14595 continue;
14596 ExprResult PostUpdateRes =
14597 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
14598 RefRes.get());
14599 if (!PostUpdateRes.isUsable())
14600 continue;
14601 ExprPostUpdates.push_back(
14602 IgnoredValueConversions(PostUpdateRes.get()).get());
14603 }
14604 }
14605 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
14606 Vars.push_back((VD || CurContext->isDependentContext())
14607 ? RefExpr->IgnoreParens()
14608 : Ref);
14609 SrcExprs.push_back(PseudoSrcExpr);
14610 DstExprs.push_back(PseudoDstExpr);
14611 AssignmentOps.push_back(AssignmentOp.get());
14612 }
14613
14614 if (Vars.empty())
14615 return nullptr;
14616
14617 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14618 Vars, SrcExprs, DstExprs, AssignmentOps,
14619 LPKind, LPKindLoc, ColonLoc,
14620 buildPreInits(Context, ExprCaptures),
14621 buildPostUpdate(*this, ExprPostUpdates));
14622}
14623
14624OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
14625 SourceLocation StartLoc,
14626 SourceLocation LParenLoc,
14627 SourceLocation EndLoc) {
14628 SmallVector<Expr *, 8> Vars;
14629 for (Expr *RefExpr : VarList) {
14630 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
14631 SourceLocation ELoc;
14632 SourceRange ERange;
14633 Expr *SimpleRefExpr = RefExpr;
14634 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14635 if (Res.second) {
14636 // It will be analyzed later.
14637 Vars.push_back(RefExpr);
14638 }
14639 ValueDecl *D = Res.first;
14640 if (!D)
14641 continue;
14642
14643 auto *VD = dyn_cast<VarDecl>(D);
14644 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14645 // in a Construct]
14646 // Variables with the predetermined data-sharing attributes may not be
14647 // listed in data-sharing attributes clauses, except for the cases
14648 // listed below. For these exceptions only, listing a predetermined
14649 // variable in a data-sharing attribute clause is allowed and overrides
14650 // the variable's predetermined data-sharing attributes.
14651 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
14652 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
14653 DVar.RefExpr) {
14654 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
14655 << getOpenMPClauseName(OMPC_shared);
14656 reportOriginalDsa(*this, DSAStack, D, DVar);
14657 continue;
14658 }
14659
14660 DeclRefExpr *Ref = nullptr;
14661 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
14662 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
14663 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
14664 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
14665 ? RefExpr->IgnoreParens()
14666 : Ref);
14667 }
14668
14669 if (Vars.empty())
14670 return nullptr;
14671
14672 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
14673}
14674
14675namespace {
14676class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
14677 DSAStackTy *Stack;
14678
14679public:
14680 bool VisitDeclRefExpr(DeclRefExpr *E) {
14681 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
14682 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
14683 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
14684 return false;
14685 if (DVar.CKind != OMPC_unknown)
14686 return true;
14687 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
14688 VD,
14689 [](OpenMPClauseKind C, bool AppliedToPointee) {
14690 return isOpenMPPrivate(C) && !AppliedToPointee;
14691 },
14692 [](OpenMPDirectiveKind) { return true; },
14693 /*FromParent=*/true);
14694 return DVarPrivate.CKind != OMPC_unknown;
14695 }
14696 return false;
14697 }
14698 bool VisitStmt(Stmt *S) {
14699 for (Stmt *Child : S->children()) {
14700 if (Child && Visit(Child))
14701 return true;
14702 }
14703 return false;
14704 }
14705 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
14706};
14707} // namespace
14708
14709namespace {
14710// Transform MemberExpression for specified FieldDecl of current class to
14711// DeclRefExpr to specified OMPCapturedExprDecl.
14712class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
14713 typedef TreeTransform<TransformExprToCaptures> BaseTransform;
14714 ValueDecl *Field = nullptr;
14715 DeclRefExpr *CapturedExpr = nullptr;
14716
14717public:
14718 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
14719 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
14720
14721 ExprResult TransformMemberExpr(MemberExpr *E) {
14722 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
14723 E->getMemberDecl() == Field) {
14724 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
14725 return CapturedExpr;
14726 }
14727 return BaseTransform::TransformMemberExpr(E);
14728 }
14729 DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
14730};
14731} // namespace
14732
14733template <typename T, typename U>
14734static T filterLookupForUDReductionAndMapper(
14735 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
14736 for (U &Set : Lookups) {
14737 for (auto *D : Set) {
14738 if (T Res = Gen(cast<ValueDecl>(D)))
14739 return Res;
14740 }
14741 }
14742 return T();
14743}
14744
14745static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
14746 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
14747
14748 for (auto RD : D->redecls()) {
14749 // Don't bother with extra checks if we already know this one isn't visible.
14750 if (RD == D)
14751 continue;
14752
14753 auto ND = cast<NamedDecl>(RD);
14754 if (LookupResult::isVisible(SemaRef, ND))
14755 return ND;
14756 }
14757
14758 return nullptr;
14759}
14760
14761static void
14762argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
14763 SourceLocation Loc, QualType Ty,
14764 SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
14765 // Find all of the associated namespaces and classes based on the
14766 // arguments we have.
14767 Sema::AssociatedNamespaceSet AssociatedNamespaces;
14768 Sema::AssociatedClassSet AssociatedClasses;
14769 OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
14770 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
14771 AssociatedClasses);
14772
14773 // C++ [basic.lookup.argdep]p3:
14774 // Let X be the lookup set produced by unqualified lookup (3.4.1)
14775 // and let Y be the lookup set produced by argument dependent
14776 // lookup (defined as follows). If X contains [...] then Y is
14777 // empty. Otherwise Y is the set of declarations found in the
14778 // namespaces associated with the argument types as described
14779 // below. The set of declarations found by the lookup of the name
14780 // is the union of X and Y.
14781 //
14782 // Here, we compute Y and add its members to the overloaded
14783 // candidate set.
14784 for (auto *NS : AssociatedNamespaces) {
14785 // When considering an associated namespace, the lookup is the
14786 // same as the lookup performed when the associated namespace is
14787 // used as a qualifier (3.4.3.2) except that:
14788 //
14789 // -- Any using-directives in the associated namespace are
14790 // ignored.
14791 //
14792 // -- Any namespace-scope friend functions declared in
14793 // associated classes are visible within their respective
14794 // namespaces even if they are not visible during an ordinary
14795 // lookup (11.4).
14796 DeclContext::lookup_result R = NS->lookup(Id.getName());
14797 for (auto *D : R) {
14798 auto *Underlying = D;
14799 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
14800 Underlying = USD->getTargetDecl();
14801
14802 if (!isa<OMPDeclareReductionDecl>(Underlying) &&
14803 !isa<OMPDeclareMapperDecl>(Underlying))
14804 continue;
14805
14806 if (!SemaRef.isVisible(D)) {
14807 D = findAcceptableDecl(SemaRef, D);
14808 if (!D)
14809 continue;
14810 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
14811 Underlying = USD->getTargetDecl();
14812 }
14813 Lookups.emplace_back();
14814 Lookups.back().addDecl(Underlying);
14815 }
14816 }
14817}
14818
14819static ExprResult
14820buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
14821 Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
14822 const DeclarationNameInfo &ReductionId, QualType Ty,
14823 CXXCastPath &BasePath, Expr *UnresolvedReduction) {
14824 if (ReductionIdScopeSpec.isInvalid())
14825 return ExprError();
14826 SmallVector<UnresolvedSet<8>, 4> Lookups;
14827 if (S) {
14828 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
14829 Lookup.suppressDiagnostics();
14830 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
14831 NamedDecl *D = Lookup.getRepresentativeDecl();
14832 do {
14833 S = S->getParent();
14834 } while (S && !S->isDeclScope(D));
14835 if (S)
14836 S = S->getParent();
14837 Lookups.emplace_back();
14838 Lookups.back().append(Lookup.begin(), Lookup.end());
14839 Lookup.clear();
14840 }
14841 } else if (auto *ULE =
14842 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
14843 Lookups.push_back(UnresolvedSet<8>());
14844 Decl *PrevD = nullptr;
14845 for (NamedDecl *D : ULE->decls()) {
14846 if (D == PrevD)
14847 Lookups.push_back(UnresolvedSet<8>());
14848 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
14849 Lookups.back().addDecl(DRD);
14850 PrevD = D;
14851 }
14852 }
14853 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
14854 Ty->isInstantiationDependentType() ||
14855 Ty->containsUnexpandedParameterPack() ||
14856 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
14857 return !D->isInvalidDecl() &&
14858 (D->getType()->isDependentType() ||
14859 D->getType()->isInstantiationDependentType() ||
14860 D->getType()->containsUnexpandedParameterPack());
14861 })) {
14862 UnresolvedSet<8> ResSet;
14863 for (const UnresolvedSet<8> &Set : Lookups) {
14864 if (Set.empty())
14865 continue;
14866 ResSet.append(Set.begin(), Set.end());
14867 // The last item marks the end of all declarations at the specified scope.
14868 ResSet.addDecl(Set[Set.size() - 1]);
14869 }
14870 return UnresolvedLookupExpr::Create(
14871 SemaRef.Context, /*NamingClass=*/nullptr,
14872 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
14873 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
14874 }
14875 // Lookup inside the classes.
14876 // C++ [over.match.oper]p3:
14877 // For a unary operator @ with an operand of a type whose
14878 // cv-unqualified version is T1, and for a binary operator @ with
14879 // a left operand of a type whose cv-unqualified version is T1 and
14880 // a right operand of a type whose cv-unqualified version is T2,
14881 // three sets of candidate functions, designated member
14882 // candidates, non-member candidates and built-in candidates, are
14883 // constructed as follows:
14884 // -- If T1 is a complete class type or a class currently being
14885 // defined, the set of member candidates is the result of the
14886 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
14887 // the set of member candidates is empty.
14888 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
14889 Lookup.suppressDiagnostics();
14890 if (const auto *TyRec = Ty->getAs<RecordType>()) {
14891 // Complete the type if it can be completed.
14892 // If the type is neither complete nor being defined, bail out now.
14893 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
14894 TyRec->getDecl()->getDefinition()) {
14895 Lookup.clear();
14896 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
14897 if (Lookup.empty()) {
14898 Lookups.emplace_back();
14899 Lookups.back().append(Lookup.begin(), Lookup.end());
14900 }
14901 }
14902 }
14903 // Perform ADL.
14904 if (SemaRef.getLangOpts().CPlusPlus)
14905 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
14906 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
14907 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
14908 if (!D->isInvalidDecl() &&
14909 SemaRef.Context.hasSameType(D->getType(), Ty))
14910 return D;
14911 return nullptr;
14912 }))
14913 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
14914 VK_LValue, Loc);
14915 if (SemaRef.getLangOpts().CPlusPlus) {
14916 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
14917 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
14918 if (!D->isInvalidDecl() &&
14919 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
14920 !Ty.isMoreQualifiedThan(D->getType()))
14921 return D;
14922 return nullptr;
14923 })) {
14924 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
14925 /*DetectVirtual=*/false);
14926 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
14927 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
14928 VD->getType().getUnqualifiedType()))) {
14929 if (SemaRef.CheckBaseClassAccess(
14930 Loc, VD->getType(), Ty, Paths.front(),
14931 /*DiagID=*/0) != Sema::AR_inaccessible) {
14932 SemaRef.BuildBasePathArray(Paths, BasePath);
14933 return SemaRef.BuildDeclRefExpr(
14934 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
14935 }
14936 }
14937 }
14938 }
14939 }
14940 if (ReductionIdScopeSpec.isSet()) {
14941 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
14942 << Ty << Range;
14943 return ExprError();
14944 }
14945 return ExprEmpty();
14946}
14947
14948namespace {
14949/// Data for the reduction-based clauses.
14950struct ReductionData {
14951 /// List of original reduction items.
14952 SmallVector<Expr *, 8> Vars;
14953 /// List of private copies of the reduction items.
14954 SmallVector<Expr *, 8> Privates;
14955 /// LHS expressions for the reduction_op expressions.
14956 SmallVector<Expr *, 8> LHSs;
14957 /// RHS expressions for the reduction_op expressions.
14958 SmallVector<Expr *, 8> RHSs;
14959 /// Reduction operation expression.
14960 SmallVector<Expr *, 8> ReductionOps;
14961 /// inscan copy operation expressions.
14962 SmallVector<Expr *, 8> InscanCopyOps;
14963 /// inscan copy temp array expressions for prefix sums.
14964 SmallVector<Expr *, 8> InscanCopyArrayTemps;
14965 /// inscan copy temp array element expressions for prefix sums.
14966 SmallVector<Expr *, 8> InscanCopyArrayElems;
14967 /// Taskgroup descriptors for the corresponding reduction items in
14968 /// in_reduction clauses.
14969 SmallVector<Expr *, 8> TaskgroupDescriptors;
14970 /// List of captures for clause.
14971 SmallVector<Decl *, 4> ExprCaptures;
14972 /// List of postupdate expressions.
14973 SmallVector<Expr *, 4> ExprPostUpdates;
14974 /// Reduction modifier.
14975 unsigned RedModifier = 0;
14976 ReductionData() = delete;
14977 /// Reserves required memory for the reduction data.
14978 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
14979 Vars.reserve(Size);
14980 Privates.reserve(Size);
14981 LHSs.reserve(Size);
14982 RHSs.reserve(Size);
14983 ReductionOps.reserve(Size);
14984 if (RedModifier == OMPC_REDUCTION_inscan) {
14985 InscanCopyOps.reserve(Size);
14986 InscanCopyArrayTemps.reserve(Size);
14987 InscanCopyArrayElems.reserve(Size);
14988 }
14989 TaskgroupDescriptors.reserve(Size);
14990 ExprCaptures.reserve(Size);
14991 ExprPostUpdates.reserve(Size);
14992 }
14993 /// Stores reduction item and reduction operation only (required for dependent
14994 /// reduction item).
14995 void push(Expr *Item, Expr *ReductionOp) {
14996 Vars.emplace_back(Item);
14997 Privates.emplace_back(nullptr);
14998 LHSs.emplace_back(nullptr);
14999 RHSs.emplace_back(nullptr);
15000 ReductionOps.emplace_back(ReductionOp);
15001 TaskgroupDescriptors.emplace_back(nullptr);
15002 if (RedModifier == OMPC_REDUCTION_inscan) {
15003 InscanCopyOps.push_back(nullptr);
15004 InscanCopyArrayTemps.push_back(nullptr);
15005 InscanCopyArrayElems.push_back(nullptr);
15006 }
15007 }
15008 /// Stores reduction data.
15009 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
15010 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
15011 Expr *CopyArrayElem) {
15012 Vars.emplace_back(Item);
15013 Privates.emplace_back(Private);
15014 LHSs.emplace_back(LHS);
15015 RHSs.emplace_back(RHS);
15016 ReductionOps.emplace_back(ReductionOp);
15017 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
15018 if (RedModifier == OMPC_REDUCTION_inscan) {
15019 InscanCopyOps.push_back(CopyOp);
15020 InscanCopyArrayTemps.push_back(CopyArrayTemp);
15021 InscanCopyArrayElems.push_back(CopyArrayElem);
15022 } else {
15023 assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&
15024 CopyArrayElem == nullptr &&
15025 "Copy operation must be used for inscan reductions only.");
15026 }
15027 }
15028};
15029} // namespace
15030
15031static bool checkOMPArraySectionConstantForReduction(
15032 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
15033 SmallVectorImpl<llvm::APSInt> &ArraySizes) {
15034 const Expr *Length = OASE->getLength();
15035 if (Length == nullptr) {
15036 // For array sections of the form [1:] or [:], we would need to analyze
15037 // the lower bound...
15038 if (OASE->getColonLocFirst().isValid())
15039 return false;
15040
15041 // This is an array subscript which has implicit length 1!
15042 SingleElement = true;
15043 ArraySizes.push_back(llvm::APSInt::get(1));
15044 } else {
15045 Expr::EvalResult Result;
15046 if (!Length->EvaluateAsInt(Result, Context))
15047 return false;
15048
15049 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
15050 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
15051 ArraySizes.push_back(ConstantLengthValue);
15052 }
15053
15054 // Get the base of this array section and walk up from there.
15055 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
15056
15057 // We require length = 1 for all array sections except the right-most to
15058 // guarantee that the memory region is contiguous and has no holes in it.
15059 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
15060 Length = TempOASE->getLength();
15061 if (Length == nullptr) {
15062 // For array sections of the form [1:] or [:], we would need to analyze
15063 // the lower bound...
15064 if (OASE->getColonLocFirst().isValid())
15065 return false;
15066
15067 // This is an array subscript which has implicit length 1!
15068 ArraySizes.push_back(llvm::APSInt::get(1));
15069 } else {
15070 Expr::EvalResult Result;
15071 if (!Length->EvaluateAsInt(Result, Context))
15072 return false;
15073
15074 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
15075 if (ConstantLengthValue.getSExtValue() != 1)
15076 return false;
15077
15078 ArraySizes.push_back(ConstantLengthValue);
15079 }
15080 Base = TempOASE->getBase()->IgnoreParenImpCasts();
15081 }
15082
15083 // If we have a single element, we don't need to add the implicit lengths.
15084 if (!SingleElement) {
15085 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
15086 // Has implicit length 1!
15087 ArraySizes.push_back(llvm::APSInt::get(1));
15088 Base = TempASE->getBase()->IgnoreParenImpCasts();
15089 }
15090 }
15091
15092 // This array section can be privatized as a single value or as a constant
15093 // sized array.
15094 return true;
15095}
15096
15097static bool actOnOMPReductionKindClause(
15098 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
15099 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
15100 SourceLocation ColonLoc, SourceLocation EndLoc,
15101 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15102 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
15103 DeclarationName DN = ReductionId.getName();
15104 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
15105 BinaryOperatorKind BOK = BO_Comma;
15106
15107 ASTContext &Context = S.Context;
15108 // OpenMP [2.14.3.6, reduction clause]
15109 // C
15110 // reduction-identifier is either an identifier or one of the following
15111 // operators: +, -, *, &, |, ^, && and ||
15112 // C++
15113 // reduction-identifier is either an id-expression or one of the following
15114 // operators: +, -, *, &, |, ^, && and ||
15115 switch (OOK) {
15116 case OO_Plus:
15117 case OO_Minus:
15118 BOK = BO_Add;
15119 break;
15120 case OO_Star:
15121 BOK = BO_Mul;
15122 break;
15123 case OO_Amp:
15124 BOK = BO_And;
15125 break;
15126 case OO_Pipe:
15127 BOK = BO_Or;
15128 break;
15129 case OO_Caret:
15130 BOK = BO_Xor;
15131 break;
15132 case OO_AmpAmp:
15133 BOK = BO_LAnd;
15134 break;
15135 case OO_PipePipe:
15136 BOK = BO_LOr;
15137 break;
15138 case OO_New:
15139 case OO_Delete:
15140 case OO_Array_New:
15141 case OO_Array_Delete:
15142 case OO_Slash:
15143 case OO_Percent:
15144 case OO_Tilde:
15145 case OO_Exclaim:
15146 case OO_Equal:
15147 case OO_Less:
15148 case OO_Greater:
15149 case OO_LessEqual:
15150 case OO_GreaterEqual:
15151 case OO_PlusEqual:
15152 case OO_MinusEqual:
15153 case OO_StarEqual:
15154 case OO_SlashEqual:
15155 case OO_PercentEqual:
15156 case OO_CaretEqual:
15157 case OO_AmpEqual:
15158 case OO_PipeEqual:
15159 case OO_LessLess:
15160 case OO_GreaterGreater:
15161 case OO_LessLessEqual:
15162 case OO_GreaterGreaterEqual:
15163 case OO_EqualEqual:
15164 case OO_ExclaimEqual:
15165 case OO_Spaceship:
15166 case OO_PlusPlus:
15167 case OO_MinusMinus:
15168 case OO_Comma:
15169 case OO_ArrowStar:
15170 case OO_Arrow:
15171 case OO_Call:
15172 case OO_Subscript:
15173 case OO_Conditional:
15174 case OO_Coawait:
15175 case NUM_OVERLOADED_OPERATORS:
15176 llvm_unreachable("Unexpected reduction identifier");
15177 case OO_None:
15178 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
15179 if (II->isStr("max"))
15180 BOK = BO_GT;
15181 else if (II->isStr("min"))
15182 BOK = BO_LT;
15183 }
15184 break;
15185 }
15186 SourceRange ReductionIdRange;
15187 if (ReductionIdScopeSpec.isValid())
15188 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
15189 else
15190 ReductionIdRange.setBegin(ReductionId.getBeginLoc());
15191 ReductionIdRange.setEnd(ReductionId.getEndLoc());
15192
15193 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
15194 bool FirstIter = true;
15195 for (Expr *RefExpr : VarList) {
15196 assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
15197 // OpenMP [2.1, C/C++]
15198 // A list item is a variable or array section, subject to the restrictions
15199 // specified in Section 2.4 on page 42 and in each of the sections
15200 // describing clauses and directives for which a list appears.
15201 // OpenMP [2.14.3.3, Restrictions, p.1]
15202 // A variable that is part of another variable (as an array or
15203 // structure element) cannot appear in a private clause.
15204 if (!FirstIter && IR != ER)
15205 ++IR;
15206 FirstIter = false;
15207 SourceLocation ELoc;
15208 SourceRange ERange;
15209 Expr *SimpleRefExpr = RefExpr;
15210 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
15211 /*AllowArraySection=*/true);
15212 if (Res.second) {
15213 // Try to find 'declare reduction' corresponding construct before using
15214 // builtin/overloaded operators.
15215 QualType Type = Context.DependentTy;
15216 CXXCastPath BasePath;
15217 ExprResult DeclareReductionRef = buildDeclareReductionRef(
15218 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
15219 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
15220 Expr *ReductionOp = nullptr;
15221 if (S.CurContext->isDependentContext() &&
15222 (DeclareReductionRef.isUnset() ||
15223 isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
15224 ReductionOp = DeclareReductionRef.get();
15225 // It will be analyzed later.
15226 RD.push(RefExpr, ReductionOp);
15227 }
15228 ValueDecl *D = Res.first;
15229 if (!D)
15230 continue;
15231
15232 Expr *TaskgroupDescriptor = nullptr;
15233 QualType Type;
15234 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
15235 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
15236 if (ASE) {
15237 Type = ASE->getType().getNonReferenceType();
15238 } else if (OASE) {
15239 QualType BaseType =
15240 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
15241 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
15242 Type = ATy->getElementType();
15243 else
15244 Type = BaseType->getPointeeType();
15245 Type = Type.getNonReferenceType();
15246 } else {
15247 Type = Context.getBaseElementType(D->getType().getNonReferenceType());
15248 }
15249 auto *VD = dyn_cast<VarDecl>(D);
15250
15251 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
15252 // A variable that appears in a private clause must not have an incomplete
15253 // type or a reference type.
15254 if (S.RequireCompleteType(ELoc, D->getType(),
15255 diag::err_omp_reduction_incomplete_type))
15256 continue;
15257 // OpenMP [2.14.3.6, reduction clause, Restrictions]
15258 // A list item that appears in a reduction clause must not be
15259 // const-qualified.
15260 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
15261 /*AcceptIfMutable*/ false, ASE || OASE))
15262 continue;
15263
15264 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
15265 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
15266 // If a list-item is a reference type then it must bind to the same object
15267 // for all threads of the team.
15268 if (!ASE && !OASE) {
15269 if (VD) {
15270 VarDecl *VDDef = VD->getDefinition();
15271 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
15272 DSARefChecker Check(Stack);
15273 if (Check.Visit(VDDef->getInit())) {
15274 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
15275 << getOpenMPClauseName(ClauseKind) << ERange;
15276 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
15277 continue;
15278 }
15279 }
15280 }
15281
15282 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
15283 // in a Construct]
15284 // Variables with the predetermined data-sharing attributes may not be
15285 // listed in data-sharing attributes clauses, except for the cases
15286 // listed below. For these exceptions only, listing a predetermined
15287 // variable in a data-sharing attribute clause is allowed and overrides
15288 // the variable's predetermined data-sharing attributes.
15289 // OpenMP [2.14.3.6, Restrictions, p.3]
15290 // Any number of reduction clauses can be specified on the directive,
15291 // but a list item can appear only once in the reduction clauses for that
15292 // directive.
15293 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
15294 if (DVar.CKind == OMPC_reduction) {
15295 S.Diag(ELoc, diag::err_omp_once_referenced)
15296 << getOpenMPClauseName(ClauseKind);
15297 if (DVar.RefExpr)
15298 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
15299 continue;
15300 }
15301 if (DVar.CKind != OMPC_unknown) {
15302 S.Diag(ELoc, diag::err_omp_wrong_dsa)
15303 << getOpenMPClauseName(DVar.CKind)
15304 << getOpenMPClauseName(OMPC_reduction);
15305 reportOriginalDsa(S, Stack, D, DVar);
15306 continue;
15307 }
15308
15309 // OpenMP [2.14.3.6, Restrictions, p.1]
15310 // A list item that appears in a reduction clause of a worksharing
15311 // construct must be shared in the parallel regions to which any of the
15312 // worksharing regions arising from the worksharing construct bind.
15313 if (isOpenMPWorksharingDirective(CurrDir) &&
15314 !isOpenMPParallelDirective(CurrDir) &&
15315 !isOpenMPTeamsDirective(CurrDir)) {
15316 DVar = Stack->getImplicitDSA(D, true);
15317 if (DVar.CKind != OMPC_shared) {
15318 S.Diag(ELoc, diag::err_omp_required_access)
15319 << getOpenMPClauseName(OMPC_reduction)
15320 << getOpenMPClauseName(OMPC_shared);
15321 reportOriginalDsa(S, Stack, D, DVar);
15322 continue;
15323 }
15324 }
15325 } else {
15326 // Threadprivates cannot be shared between threads, so dignose if the base
15327 // is a threadprivate variable.
15328 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
15329 if (DVar.CKind == OMPC_threadprivate) {
15330 S.Diag(ELoc, diag::err_omp_wrong_dsa)
15331 << getOpenMPClauseName(DVar.CKind)
15332 << getOpenMPClauseName(OMPC_reduction);
15333 reportOriginalDsa(S, Stack, D, DVar);
15334 continue;
15335 }
15336 }
15337
15338 // Try to find 'declare reduction' corresponding construct before using
15339 // builtin/overloaded operators.
15340 CXXCastPath BasePath;
15341 ExprResult DeclareReductionRef = buildDeclareReductionRef(
15342 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
15343 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
15344 if (DeclareReductionRef.isInvalid())
15345 continue;
15346 if (S.CurContext->isDependentContext() &&
15347 (DeclareReductionRef.isUnset() ||
15348 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
15349 RD.push(RefExpr, DeclareReductionRef.get());
15350 continue;
15351 }
15352 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
15353 // Not allowed reduction identifier is found.
15354 S.Diag(ReductionId.getBeginLoc(),
15355 diag::err_omp_unknown_reduction_identifier)
15356 << Type << ReductionIdRange;
15357 continue;
15358 }
15359
15360 // OpenMP [2.14.3.6, reduction clause, Restrictions]
15361 // The type of a list item that appears in a reduction clause must be valid
15362 // for the reduction-identifier. For a max or min reduction in C, the type
15363 // of the list item must be an allowed arithmetic data type: char, int,
15364 // float, double, or _Bool, possibly modified with long, short, signed, or
15365 // unsigned. For a max or min reduction in C++, the type of the list item
15366 // must be an allowed arithmetic data type: char, wchar_t, int, float,
15367 // double, or bool, possibly modified with long, short, signed, or unsigned.
15368 if (DeclareReductionRef.isUnset()) {
15369 if ((BOK == BO_GT || BOK == BO_LT) &&
15370 !(Type->isScalarType() ||
15371 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
15372 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
15373 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
15374 if (!ASE && !OASE) {
15375 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15376 VarDecl::DeclarationOnly;
15377 S.Diag(D->getLocation(),
15378 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15379 << D;
15380 }
15381 continue;
15382 }
15383 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
15384 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
15385 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
15386 << getOpenMPClauseName(ClauseKind);
15387 if (!ASE && !OASE) {
15388 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15389 VarDecl::DeclarationOnly;
15390 S.Diag(D->getLocation(),
15391 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15392 << D;
15393 }
15394 continue;
15395 }
15396 }
15397
15398 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
15399 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
15400 D->hasAttrs() ? &D->getAttrs() : nullptr);
15401 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
15402 D->hasAttrs() ? &D->getAttrs() : nullptr);
15403 QualType PrivateTy = Type;
15404
15405 // Try if we can determine constant lengths for all array sections and avoid
15406 // the VLA.
15407 bool ConstantLengthOASE = false;
15408 if (OASE) {
15409 bool SingleElement;
15410 llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
15411 ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
15412 Context, OASE, SingleElement, ArraySizes);
15413
15414 // If we don't have a single element, we must emit a constant array type.
15415 if (ConstantLengthOASE && !SingleElement) {
15416 for (llvm::APSInt &Size : ArraySizes)
15417 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
15418 ArrayType::Normal,
15419 /*IndexTypeQuals=*/0);
15420 }
15421 }
15422
15423 if ((OASE && !ConstantLengthOASE) ||
15424 (!OASE && !ASE &&
15425 D->getType().getNonReferenceType()->isVariablyModifiedType())) {
15426 if (!Context.getTargetInfo().isVLASupported()) {
15427 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
15428 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
15429 S.Diag(ELoc, diag::note_vla_unsupported);
15430 continue;
15431 } else {
15432 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
15433 S.targetDiag(ELoc, diag::note_vla_unsupported);
15434 }
15435 }
15436 // For arrays/array sections only:
15437 // Create pseudo array type for private copy. The size for this array will
15438 // be generated during codegen.
15439 // For array subscripts or single variables Private Ty is the same as Type
15440 // (type of the variable or single array element).
15441 PrivateTy = Context.getVariableArrayType(
15442 Type,
15443 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
15444 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
15445 } else if (!ASE && !OASE &&
15446 Context.getAsArrayType(D->getType().getNonReferenceType())) {
15447 PrivateTy = D->getType().getNonReferenceType();
15448 }
15449 // Private copy.
15450 VarDecl *PrivateVD =
15451 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
15452 D->hasAttrs() ? &D->getAttrs() : nullptr,
15453 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15454 // Add initializer for private variable.
15455 Expr *Init = nullptr;
15456 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
15457 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
15458 if (DeclareReductionRef.isUsable()) {
15459 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
15460 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
15461 if (DRD->getInitializer()) {
15462 S.ActOnUninitializedDecl(PrivateVD);
15463 Init = DRDRef;
15464 RHSVD->setInit(DRDRef);
15465 RHSVD->setInitStyle(VarDecl::CallInit);
15466 }
15467 } else {
15468 switch (BOK) {
15469 case BO_Add:
15470 case BO_Xor:
15471 case BO_Or:
15472 case BO_LOr:
15473 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
15474 if (Type->isScalarType() || Type->isAnyComplexType())
15475 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
15476 break;
15477 case BO_Mul:
15478 case BO_LAnd:
15479 if (Type->isScalarType() || Type->isAnyComplexType()) {
15480 // '*' and '&&' reduction ops - initializer is '1'.
15481 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
15482 }
15483 break;
15484 case BO_And: {
15485 // '&' reduction op - initializer is '~0'.
15486 QualType OrigType = Type;
15487 if (auto *ComplexTy = OrigType->getAs<ComplexType>())
15488 Type = ComplexTy->getElementType();
15489 if (Type->isRealFloatingType()) {
15490 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
15491 Context.getFloatTypeSemantics(Type),
15492 Context.getTypeSize(Type));
15493 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
15494 Type, ELoc);
15495 } else if (Type->isScalarType()) {
15496 uint64_t Size = Context.getTypeSize(Type);
15497 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
15498 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
15499 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
15500 }
15501 if (Init && OrigType->isAnyComplexType()) {
15502 // Init = 0xFFFF + 0xFFFFi;
15503 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
15504 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
15505 }
15506 Type = OrigType;
15507 break;
15508 }
15509 case BO_LT:
15510 case BO_GT: {
15511 // 'min' reduction op - initializer is 'Largest representable number in
15512 // the reduction list item type'.
15513 // 'max' reduction op - initializer is 'Least representable number in
15514 // the reduction list item type'.
15515 if (Type->isIntegerType() || Type->isPointerType()) {
15516 bool IsSigned = Type->hasSignedIntegerRepresentation();
15517 uint64_t Size = Context.getTypeSize(Type);
15518 QualType IntTy =
15519 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
15520 llvm::APInt InitValue =
15521 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
15522 : llvm::APInt::getMinValue(Size)
15523 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
15524 : llvm::APInt::getMaxValue(Size);
15525 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
15526 if (Type->isPointerType()) {
15527 // Cast to pointer type.
15528 ExprResult CastExpr = S.BuildCStyleCastExpr(
15529 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
15530 if (CastExpr.isInvalid())
15531 continue;
15532 Init = CastExpr.get();
15533 }
15534 } else if (Type->isRealFloatingType()) {
15535 llvm::APFloat InitValue = llvm::APFloat::getLargest(
15536 Context.getFloatTypeSemantics(Type), BOK != BO_LT);
15537 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
15538 Type, ELoc);
15539 }
15540 break;
15541 }
15542 case BO_PtrMemD:
15543 case BO_PtrMemI:
15544 case BO_MulAssign:
15545 case BO_Div:
15546 case BO_Rem:
15547 case BO_Sub:
15548 case BO_Shl:
15549 case BO_Shr:
15550 case BO_LE:
15551 case BO_GE:
15552 case BO_EQ:
15553 case BO_NE:
15554 case BO_Cmp:
15555 case BO_AndAssign:
15556 case BO_XorAssign:
15557 case BO_OrAssign:
15558 case BO_Assign:
15559 case BO_AddAssign:
15560 case BO_SubAssign:
15561 case BO_DivAssign:
15562 case BO_RemAssign:
15563 case BO_ShlAssign:
15564 case BO_ShrAssign:
15565 case BO_Comma:
15566 llvm_unreachable("Unexpected reduction operation");
15567 }
15568 }
15569 if (Init && DeclareReductionRef.isUnset()) {
15570 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
15571 // Store initializer for single element in private copy. Will be used
15572 // during codegen.
15573 PrivateVD->setInit(RHSVD->getInit());
15574 PrivateVD->setInitStyle(RHSVD->getInitStyle());
15575 } else if (!Init) {
15576 S.ActOnUninitializedDecl(RHSVD);
15577 // Store initializer for single element in private copy. Will be used
15578 // during codegen.
15579 PrivateVD->setInit(RHSVD->getInit());
15580 PrivateVD->setInitStyle(RHSVD->getInitStyle());
15581 }
15582 if (RHSVD->isInvalidDecl())
15583 continue;
15584 if (!RHSVD->hasInit() &&
15585 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) {
15586 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
15587 << Type << ReductionIdRange;
15588 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15589 VarDecl::DeclarationOnly;
15590 S.Diag(D->getLocation(),
15591 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15592 << D;
15593 continue;
15594 }
15595 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
15596 ExprResult ReductionOp;
15597 if (DeclareReductionRef.isUsable()) {
15598 QualType RedTy = DeclareReductionRef.get()->getType();
15599 QualType PtrRedTy = Context.getPointerType(RedTy);
15600 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
15601 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
15602 if (!BasePath.empty()) {
15603 LHS = S.DefaultLvalueConversion(LHS.get());
15604 RHS = S.DefaultLvalueConversion(RHS.get());
15605 LHS = ImplicitCastExpr::Create(
15606 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
15607 LHS.get()->getValueKind(), FPOptionsOverride());
15608 RHS = ImplicitCastExpr::Create(
15609 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
15610 RHS.get()->getValueKind(), FPOptionsOverride());
15611 }
15612 FunctionProtoType::ExtProtoInfo EPI;
15613 QualType Params[] = {PtrRedTy, PtrRedTy};
15614 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
15615 auto *OVE = new (Context) OpaqueValueExpr(
15616 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
15617 S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
15618 Expr *Args[] = {LHS.get(), RHS.get()};
15619 ReductionOp =
15620 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc,
15621 S.CurFPFeatureOverrides());
15622 } else {
15623 ReductionOp = S.BuildBinOp(
15624 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
15625 if (ReductionOp.isUsable()) {
15626 if (BOK != BO_LT && BOK != BO_GT) {
15627 ReductionOp =
15628 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
15629 BO_Assign, LHSDRE, ReductionOp.get());
15630 } else {
15631 auto *ConditionalOp = new (Context)
15632 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
15633 Type, VK_LValue, OK_Ordinary);
15634 ReductionOp =
15635 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
15636 BO_Assign, LHSDRE, ConditionalOp);
15637 }
15638 if (ReductionOp.isUsable())
15639 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
15640 /*DiscardedValue*/ false);
15641 }
15642 if (!ReductionOp.isUsable())
15643 continue;
15644 }
15645
15646 // Add copy operations for inscan reductions.
15647 // LHS = RHS;
15648 ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
15649 if (ClauseKind == OMPC_reduction &&
15650 RD.RedModifier == OMPC_REDUCTION_inscan) {
15651 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
15652 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
15653 RHS.get());
15654 if (!CopyOpRes.isUsable())
15655 continue;
15656 CopyOpRes =
15657 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
15658 if (!CopyOpRes.isUsable())
15659 continue;
15660 // For simd directive and simd-based directives in simd mode no need to
15661 // construct temp array, need just a single temp element.
15662 if (Stack->getCurrentDirective() == OMPD_simd ||
15663 (S.getLangOpts().OpenMPSimd &&
15664 isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
15665 VarDecl *TempArrayVD =
15666 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
15667 D->hasAttrs() ? &D->getAttrs() : nullptr);
15668 // Add a constructor to the temp decl.
15669 S.ActOnUninitializedDecl(TempArrayVD);
15670 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
15671 } else {
15672 // Build temp array for prefix sum.
15673 auto *Dim = new (S.Context)
15674 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
15675 QualType ArrayTy =
15676 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal,
15677 /*IndexTypeQuals=*/0, {ELoc, ELoc});
15678 VarDecl *TempArrayVD =
15679 buildVarDecl(S, ELoc, ArrayTy, D->getName(),
15680 D->hasAttrs() ? &D->getAttrs() : nullptr);
15681 // Add a constructor to the temp decl.
15682 S.ActOnUninitializedDecl(TempArrayVD);
15683 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
15684 TempArrayElem =
15685 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
15686 auto *Idx = new (S.Context)
15687 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
15688 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
15689 ELoc, Idx, ELoc);
15690 }
15691 }
15692
15693 // OpenMP [2.15.4.6, Restrictions, p.2]
15694 // A list item that appears in an in_reduction clause of a task construct
15695 // must appear in a task_reduction clause of a construct associated with a
15696 // taskgroup region that includes the participating task in its taskgroup
15697 // set. The construct associated with the innermost region that meets this
15698 // condition must specify the same reduction-identifier as the in_reduction
15699 // clause.
15700 if (ClauseKind == OMPC_in_reduction) {
15701 SourceRange ParentSR;
15702 BinaryOperatorKind ParentBOK;
15703 const Expr *ParentReductionOp = nullptr;
15704 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
15705 DSAStackTy::DSAVarData ParentBOKDSA =
15706 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
15707 ParentBOKTD);
15708 DSAStackTy::DSAVarData ParentReductionOpDSA =
15709 Stack->getTopMostTaskgroupReductionData(
15710 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
15711 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
15712 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
15713 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
15714 (DeclareReductionRef.isUsable() && IsParentBOK) ||
15715 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
15716 bool EmitError = true;
15717 if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
15718 llvm::FoldingSetNodeID RedId, ParentRedId;
15719 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
15720 DeclareReductionRef.get()->Profile(RedId, Context,
15721 /*Canonical=*/true);
15722 EmitError = RedId != ParentRedId;
15723 }
15724 if (EmitError) {
15725 S.Diag(ReductionId.getBeginLoc(),
15726 diag::err_omp_reduction_identifier_mismatch)
15727 << ReductionIdRange << RefExpr->getSourceRange();
15728 S.Diag(ParentSR.getBegin(),
15729 diag::note_omp_previous_reduction_identifier)
15730 << ParentSR
15731 << (IsParentBOK ? ParentBOKDSA.RefExpr
15732 : ParentReductionOpDSA.RefExpr)
15733 ->getSourceRange();
15734 continue;
15735 }
15736 }
15737 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
15738 }
15739
15740 DeclRefExpr *Ref = nullptr;
15741 Expr *VarsExpr = RefExpr->IgnoreParens();
15742 if (!VD && !S.CurContext->isDependentContext()) {
15743 if (ASE || OASE) {
15744 TransformExprToCaptures RebuildToCapture(S, D);
15745 VarsExpr =
15746 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
15747 Ref = RebuildToCapture.getCapturedExpr();
15748 } else {
15749 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
15750 }
15751 if (!S.isOpenMPCapturedDecl(D)) {
15752 RD.ExprCaptures.emplace_back(Ref->getDecl());
15753 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
15754 ExprResult RefRes = S.DefaultLvalueConversion(Ref);
15755 if (!RefRes.isUsable())
15756 continue;
15757 ExprResult PostUpdateRes =
15758 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
15759 RefRes.get());
15760 if (!PostUpdateRes.isUsable())
15761 continue;
15762 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
15763 Stack->getCurrentDirective() == OMPD_taskgroup) {
15764 S.Diag(RefExpr->getExprLoc(),
15765 diag::err_omp_reduction_non_addressable_expression)
15766 << RefExpr->getSourceRange();
15767 continue;
15768 }
15769 RD.ExprPostUpdates.emplace_back(
15770 S.IgnoredValueConversions(PostUpdateRes.get()).get());
15771 }
15772 }
15773 }
15774 // All reduction items are still marked as reduction (to do not increase
15775 // code base size).
15776 unsigned Modifier = RD.RedModifier;
15777 // Consider task_reductions as reductions with task modifier. Required for
15778 // correct analysis of in_reduction clauses.
15779 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
15780 Modifier = OMPC_REDUCTION_task;
15781 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
15782 ASE || OASE);
15783 if (Modifier == OMPC_REDUCTION_task &&
15784 (CurrDir == OMPD_taskgroup ||
15785 ((isOpenMPParallelDirective(CurrDir) ||
15786 isOpenMPWorksharingDirective(CurrDir)) &&
15787 !isOpenMPSimdDirective(CurrDir)))) {
15788 if (DeclareReductionRef.isUsable())
15789 Stack->addTaskgroupReductionData(D, ReductionIdRange,
15790 DeclareReductionRef.get());
15791 else
15792 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
15793 }
15794 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
15795 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
15796 TempArrayElem.get());
15797 }
15798 return RD.Vars.empty();
15799}
15800
15801OMPClause *Sema::ActOnOpenMPReductionClause(
15802 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
15803 SourceLocation StartLoc, SourceLocation LParenLoc,
15804 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
15805 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15806 ArrayRef<Expr *> UnresolvedReductions) {
15807 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
15808 Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
15809 << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
15810 /*Last=*/OMPC_REDUCTION_unknown)
15811 << getOpenMPClauseName(OMPC_reduction);
15812 return nullptr;
15813 }
15814 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
15815 // A reduction clause with the inscan reduction-modifier may only appear on a
15816 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
15817 // construct, a parallel worksharing-loop construct or a parallel
15818 // worksharing-loop SIMD construct.
15819 if (Modifier == OMPC_REDUCTION_inscan &&
15820 (DSAStack->getCurrentDirective() != OMPD_for &&
15821 DSAStack->getCurrentDirective() != OMPD_for_simd &&
15822 DSAStack->getCurrentDirective() != OMPD_simd &&
15823 DSAStack->getCurrentDirective() != OMPD_parallel_for &&
15824 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) {
15825 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
15826 return nullptr;
15827 }
15828
15829 ReductionData RD(VarList.size(), Modifier);
15830 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
15831 StartLoc, LParenLoc, ColonLoc, EndLoc,
15832 ReductionIdScopeSpec, ReductionId,
15833 UnresolvedReductions, RD))
15834 return nullptr;
15835
15836 return OMPReductionClause::Create(
15837 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
15838 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15839 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
15840 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
15841 buildPreInits(Context, RD.ExprCaptures),
15842 buildPostUpdate(*this, RD.ExprPostUpdates));
15843}
15844
15845OMPClause *Sema::ActOnOpenMPTaskReductionClause(
15846 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
15847 SourceLocation ColonLoc, SourceLocation EndLoc,
15848 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15849 ArrayRef<Expr *> UnresolvedReductions) {
15850 ReductionData RD(VarList.size());
15851 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
15852 StartLoc, LParenLoc, ColonLoc, EndLoc,
15853 ReductionIdScopeSpec, ReductionId,
15854 UnresolvedReductions, RD))
15855 return nullptr;
15856
15857 return OMPTaskReductionClause::Create(
15858 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
15859 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15860 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
15861 buildPreInits(Context, RD.ExprCaptures),
15862 buildPostUpdate(*this, RD.ExprPostUpdates));
15863}
15864
15865OMPClause *Sema::ActOnOpenMPInReductionClause(
15866 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
15867 SourceLocation ColonLoc, SourceLocation EndLoc,
15868 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15869 ArrayRef<Expr *> UnresolvedReductions) {
15870 ReductionData RD(VarList.size());
15871 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
15872 StartLoc, LParenLoc, ColonLoc, EndLoc,
15873 ReductionIdScopeSpec, ReductionId,
15874 UnresolvedReductions, RD))
15875 return nullptr;
15876
15877 return OMPInReductionClause::Create(
15878 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
15879 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15880 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
15881 buildPreInits(Context, RD.ExprCaptures),
15882 buildPostUpdate(*this, RD.ExprPostUpdates));
15883}
15884
15885bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
15886 SourceLocation LinLoc) {
15887 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
15888 LinKind == OMPC_LINEAR_unknown) {
15889 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
15890 return true;
15891 }
15892 return false;
15893}
15894
15895bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
15896 OpenMPLinearClauseKind LinKind, QualType Type,
15897 bool IsDeclareSimd) {
15898 const auto *VD = dyn_cast_or_null<VarDecl>(D);
15899 // A variable must not have an incomplete type or a reference type.
15900 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
15901 return true;
15902 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
15903 !Type->isReferenceType()) {
15904 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
15905 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
15906 return true;
15907 }
15908 Type = Type.getNonReferenceType();
15909
15910 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
15911 // A variable that is privatized must not have a const-qualified type
15912 // unless it is of class type with a mutable member. This restriction does
15913 // not apply to the firstprivate clause, nor to the linear clause on
15914 // declarative directives (like declare simd).
15915 if (!IsDeclareSimd &&
15916 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
15917 return true;
15918
15919 // A list item must be of integral or pointer type.
15920 Type = Type.getUnqualifiedType().getCanonicalType();
15921 const auto *Ty = Type.getTypePtrOrNull();
15922 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
15923 !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
15924 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
15925 if (D) {
15926 bool IsDecl =
15927 !VD ||
15928 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15929 Diag(D->getLocation(),
15930 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15931 << D;
15932 }
15933 return true;
15934 }
15935 return false;
15936}
15937
15938OMPClause *Sema::ActOnOpenMPLinearClause(
15939 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
15940 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
15941 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
15942 SmallVector<Expr *, 8> Vars;
15943 SmallVector<Expr *, 8> Privates;
15944 SmallVector<Expr *, 8> Inits;
15945 SmallVector<Decl *, 4> ExprCaptures;
15946 SmallVector<Expr *, 4> ExprPostUpdates;
15947 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
15948 LinKind = OMPC_LINEAR_val;
15949 for (Expr *RefExpr : VarList) {
15950 assert(RefExpr && "NULL expr in OpenMP linear clause.");
15951 SourceLocation ELoc;
15952 SourceRange ERange;
15953 Expr *SimpleRefExpr = RefExpr;
15954 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15955 if (Res.second) {
15956 // It will be analyzed later.
15957 Vars.push_back(RefExpr);
15958 Privates.push_back(nullptr);
15959 Inits.push_back(nullptr);
15960 }
15961 ValueDecl *D = Res.first;
15962 if (!D)
15963 continue;
15964
15965 QualType Type = D->getType();
15966 auto *VD = dyn_cast<VarDecl>(D);
15967
15968 // OpenMP [2.14.3.7, linear clause]
15969 // A list-item cannot appear in more than one linear clause.
15970 // A list-item that appears in a linear clause cannot appear in any
15971 // other data-sharing attribute clause.
15972 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
15973 if (DVar.RefExpr) {
15974 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
15975 << getOpenMPClauseName(OMPC_linear);
15976 reportOriginalDsa(*this, DSAStack, D, DVar);
15977 continue;
15978 }
15979
15980 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
15981 continue;
15982 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
15983
15984 // Build private copy of original var.
15985 VarDecl *Private =
15986 buildVarDecl(*this, ELoc, Type, D->getName(),
15987 D->hasAttrs() ? &D->getAttrs() : nullptr,
15988 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15989 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
15990 // Build var to save initial value.
15991 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
15992 Expr *InitExpr;
15993 DeclRefExpr *Ref = nullptr;
15994 if (!VD && !CurContext->isDependentContext()) {
15995 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
15996 if (!isOpenMPCapturedDecl(D)) {
15997 ExprCaptures.push_back(Ref->getDecl());
15998 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
15999 ExprResult RefRes = DefaultLvalueConversion(Ref);
16000 if (!RefRes.isUsable())
16001 continue;
16002 ExprResult PostUpdateRes =
16003 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
16004 SimpleRefExpr, RefRes.get());
16005 if (!PostUpdateRes.isUsable())
16006 continue;
16007 ExprPostUpdates.push_back(
16008 IgnoredValueConversions(PostUpdateRes.get()).get());
16009 }
16010 }
16011 }
16012 if (LinKind == OMPC_LINEAR_uval)
16013 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
16014 else
16015 InitExpr = VD ? SimpleRefExpr : Ref;
16016 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
16017 /*DirectInit=*/false);
16018 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
16019
16020 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
16021 Vars.push_back((VD || CurContext->isDependentContext())
16022 ? RefExpr->IgnoreParens()
16023 : Ref);
16024 Privates.push_back(PrivateRef);
16025 Inits.push_back(InitRef);
16026 }
16027
16028 if (Vars.empty())
16029 return nullptr;
16030
16031 Expr *StepExpr = Step;
16032 Expr *CalcStepExpr = nullptr;
16033 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
16034 !Step->isInstantiationDependent() &&
16035 !Step->containsUnexpandedParameterPack()) {
16036 SourceLocation StepLoc = Step->getBeginLoc();
16037 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
16038 if (Val.isInvalid())
16039 return nullptr;
16040 StepExpr = Val.get();
16041
16042 // Build var to save the step value.
16043 VarDecl *SaveVar =
16044 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
16045 ExprResult SaveRef =
16046 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
16047 ExprResult CalcStep =
16048 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
16049 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
16050
16051 // Warn about zero linear step (it would be probably better specified as
16052 // making corresponding variables 'const').
16053 if (Optional<llvm::APSInt> Result =
16054 StepExpr->getIntegerConstantExpr(Context)) {
16055 if (!Result->isNegative() && !Result->isStrictlyPositive())
16056 Diag(StepLoc, diag::warn_omp_linear_step_zero)
16057 << Vars[0] << (Vars.size() > 1);
16058 } else if (CalcStep.isUsable()) {
16059 // Calculate the step beforehand instead of doing this on each iteration.
16060 // (This is not used if the number of iterations may be kfold-ed).
16061 CalcStepExpr = CalcStep.get();
16062 }
16063 }
16064
16065 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
16066 ColonLoc, EndLoc, Vars, Privates, Inits,
16067 StepExpr, CalcStepExpr,
16068 buildPreInits(Context, ExprCaptures),
16069 buildPostUpdate(*this, ExprPostUpdates));
16070}
16071
16072static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
16073 Expr *NumIterations, Sema &SemaRef,
16074 Scope *S, DSAStackTy *Stack) {
16075 // Walk the vars and build update/final expressions for the CodeGen.
16076 SmallVector<Expr *, 8> Updates;
16077 SmallVector<Expr *, 8> Finals;
16078 SmallVector<Expr *, 8> UsedExprs;
16079 Expr *Step = Clause.getStep();
16080 Expr *CalcStep = Clause.getCalcStep();
16081 // OpenMP [2.14.3.7, linear clause]
16082 // If linear-step is not specified it is assumed to be 1.
16083 if (!Step)
16084 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
16085 else if (CalcStep)
16086 Step = cast<BinaryOperator>(CalcStep)->getLHS();
16087 bool HasErrors = false;
16088 auto CurInit = Clause.inits().begin();
16089 auto CurPrivate = Clause.privates().begin();
16090 OpenMPLinearClauseKind LinKind = Clause.getModifier();
16091 for (Expr *RefExpr : Clause.varlists()) {
16092 SourceLocation ELoc;
16093 SourceRange ERange;
16094 Expr *SimpleRefExpr = RefExpr;
16095 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
16096 ValueDecl *D = Res.first;
16097 if (Res.second || !D) {
16098 Updates.push_back(nullptr);
16099 Finals.push_back(nullptr);
16100 HasErrors = true;
16101 continue;
16102 }
16103 auto &&Info = Stack->isLoopControlVariable(D);
16104 // OpenMP [2.15.11, distribute simd Construct]
16105 // A list item may not appear in a linear clause, unless it is the loop
16106 // iteration variable.
16107 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
16108 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
16109 SemaRef.Diag(ELoc,
16110 diag::err_omp_linear_distribute_var_non_loop_iteration);
16111 Updates.push_back(nullptr);
16112 Finals.push_back(nullptr);
16113 HasErrors = true;
16114 continue;
16115 }
16116 Expr *InitExpr = *CurInit;
16117
16118 // Build privatized reference to the current linear var.
16119 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
16120 Expr *CapturedRef;
16121 if (LinKind == OMPC_LINEAR_uval)
16122 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
16123 else
16124 CapturedRef =
16125 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
16126 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
16127 /*RefersToCapture=*/true);
16128
16129 // Build update: Var = InitExpr + IV * Step
16130 ExprResult Update;
16131 if (!Info.first)
16132 Update = buildCounterUpdate(
16133 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
16134 /*Subtract=*/false, /*IsNonRectangularLB=*/false);
16135 else
16136 Update = *CurPrivate;
16137 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
16138 /*DiscardedValue*/ false);
16139
16140 // Build final: Var = InitExpr + NumIterations * Step
16141 ExprResult Final;
16142 if (!Info.first)
16143 Final =
16144 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
16145 InitExpr, NumIterations, Step, /*Subtract=*/false,
16146 /*IsNonRectangularLB=*/false);
16147 else
16148 Final = *CurPrivate;
16149 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
16150 /*DiscardedValue*/ false);
16151
16152 if (!Update.isUsable() || !Final.isUsable()) {
16153 Updates.push_back(nullptr);
16154 Finals.push_back(nullptr);
16155 UsedExprs.push_back(nullptr);
16156 HasErrors = true;
16157 } else {
16158 Updates.push_back(Update.get());
16159 Finals.push_back(Final.get());
16160 if (!Info.first)
16161 UsedExprs.push_back(SimpleRefExpr);
16162 }
16163 ++CurInit;
16164 ++CurPrivate;
16165 }
16166 if (Expr *S = Clause.getStep())
16167 UsedExprs.push_back(S);
16168 // Fill the remaining part with the nullptr.
16169 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
16170 Clause.setUpdates(Updates);
16171 Clause.setFinals(Finals);
16172 Clause.setUsedExprs(UsedExprs);
16173 return HasErrors;
16174}
16175
16176OMPClause *Sema::ActOnOpenMPAlignedClause(
16177 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
16178 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
16179 SmallVector<Expr *, 8> Vars;
16180 for (Expr *RefExpr : VarList) {
16181 assert(RefExpr && "NULL expr in OpenMP linear clause.");
16182 SourceLocation ELoc;
16183 SourceRange ERange;
16184 Expr *SimpleRefExpr = RefExpr;
16185 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16186 if (Res.second) {
16187 // It will be analyzed later.
16188 Vars.push_back(RefExpr);
16189 }
16190 ValueDecl *D = Res.first;
16191 if (!D)
16192 continue;
16193
16194 QualType QType = D->getType();
16195 auto *VD = dyn_cast<VarDecl>(D);
16196
16197 // OpenMP [2.8.1, simd construct, Restrictions]
16198 // The type of list items appearing in the aligned clause must be
16199 // array, pointer, reference to array, or reference to pointer.
16200 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
16201 const Type *Ty = QType.getTypePtrOrNull();
16202 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
16203 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
16204 << QType << getLangOpts().CPlusPlus << ERange;
16205 bool IsDecl =
16206 !VD ||
16207 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
16208 Diag(D->getLocation(),
16209 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16210 << D;
16211 continue;
16212 }
16213
16214 // OpenMP [2.8.1, simd construct, Restrictions]
16215 // A list-item cannot appear in more than one aligned clause.
16216 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
16217 Diag(ELoc, diag::err_omp_used_in_clause_twice)
16218 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
16219 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
16220 << getOpenMPClauseName(OMPC_aligned);
16221 continue;
16222 }
16223
16224 DeclRefExpr *Ref = nullptr;
16225 if (!VD && isOpenMPCapturedDecl(D))
16226 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
16227 Vars.push_back(DefaultFunctionArrayConversion(
16228 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
16229 .get());
16230 }
16231
16232 // OpenMP [2.8.1, simd construct, Description]
16233 // The parameter of the aligned clause, alignment, must be a constant
16234 // positive integer expression.
16235 // If no optional parameter is specified, implementation-defined default
16236 // alignments for SIMD instructions on the target platforms are assumed.
16237 if (Alignment != nullptr) {
16238 ExprResult AlignResult =
16239 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
16240 if (AlignResult.isInvalid())
16241 return nullptr;
16242 Alignment = AlignResult.get();
16243 }
16244 if (Vars.empty())
16245 return nullptr;
16246
16247 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
16248 EndLoc, Vars, Alignment);
16249}
16250
16251OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
16252 SourceLocation StartLoc,
16253 SourceLocation LParenLoc,
16254 SourceLocation EndLoc) {
16255 SmallVector<Expr *, 8> Vars;
16256 SmallVector<Expr *, 8> SrcExprs;
16257 SmallVector<Expr *, 8> DstExprs;
16258 SmallVector<Expr *, 8> AssignmentOps;
16259 for (Expr *RefExpr : VarList) {
16260 assert(RefExpr && "NULL expr in OpenMP copyin clause.");
16261 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
16262 // It will be analyzed later.
16263 Vars.push_back(RefExpr);
16264 SrcExprs.push_back(nullptr);
16265 DstExprs.push_back(nullptr);
16266 AssignmentOps.push_back(nullptr);
16267 continue;
16268 }
16269
16270 SourceLocation ELoc = RefExpr->getExprLoc();
16271 // OpenMP [2.1, C/C++]
16272 // A list item is a variable name.
16273 // OpenMP [2.14.4.1, Restrictions, p.1]
16274 // A list item that appears in a copyin clause must be threadprivate.
16275 auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
16276 if (!DE || !isa<VarDecl>(DE->getDecl())) {
16277 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
16278 << 0 << RefExpr->getSourceRange();
16279 continue;
16280 }
16281
16282 Decl *D = DE->getDecl();
16283 auto *VD = cast<VarDecl>(D);
16284
16285 QualType Type = VD->getType();
16286 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
16287 // It will be analyzed later.
16288 Vars.push_back(DE);
16289 SrcExprs.push_back(nullptr);
16290 DstExprs.push_back(nullptr);
16291 AssignmentOps.push_back(nullptr);
16292 continue;
16293 }
16294
16295 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
16296 // A list item that appears in a copyin clause must be threadprivate.
16297 if (!DSAStack->isThreadPrivate(VD)) {
16298 Diag(ELoc, diag::err_omp_required_access)
16299 << getOpenMPClauseName(OMPC_copyin)
16300 << getOpenMPDirectiveName(OMPD_threadprivate);
16301 continue;
16302 }
16303
16304 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
16305 // A variable of class type (or array thereof) that appears in a
16306 // copyin clause requires an accessible, unambiguous copy assignment
16307 // operator for the class type.
16308 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
16309 VarDecl *SrcVD =
16310 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
16311 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
16312 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
16313 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
16314 VarDecl *DstVD =
16315 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
16316 VD->hasAttrs() ? &VD->getAttrs() : nullptr);
16317 DeclRefExpr *PseudoDstExpr =
16318 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
16319 // For arrays generate assignment operation for single element and replace
16320 // it by the original array element in CodeGen.
16321 ExprResult AssignmentOp =
16322 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
16323 PseudoSrcExpr);
16324 if (AssignmentOp.isInvalid())
16325 continue;
16326 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
16327 /*DiscardedValue*/ false);
16328 if (AssignmentOp.isInvalid())
16329 continue;
16330
16331 DSAStack->addDSA(VD, DE, OMPC_copyin);
16332 Vars.push_back(DE);
16333 SrcExprs.push_back(PseudoSrcExpr);
16334 DstExprs.push_back(PseudoDstExpr);
16335 AssignmentOps.push_back(AssignmentOp.get());
16336 }
16337
16338 if (Vars.empty())
16339 return nullptr;
16340
16341 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
16342 SrcExprs, DstExprs, AssignmentOps);
16343}
16344
16345OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
16346 SourceLocation StartLoc,
16347 SourceLocation LParenLoc,
16348 SourceLocation EndLoc) {
16349 SmallVector<Expr *, 8> Vars;
16350 SmallVector<Expr *, 8> SrcExprs;
16351 SmallVector<Expr *, 8> DstExprs;
16352 SmallVector<Expr *, 8> AssignmentOps;
16353 for (Expr *RefExpr : VarList) {
16354 assert(RefExpr && "NULL expr in OpenMP linear clause.");
16355 SourceLocation ELoc;
16356 SourceRange ERange;
16357 Expr *SimpleRefExpr = RefExpr;
16358 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16359 if (Res.second) {
16360 // It will be analyzed later.
16361 Vars.push_back(RefExpr);
16362 SrcExprs.push_back(nullptr);
16363 DstExprs.push_back(nullptr);
16364 AssignmentOps.push_back(nullptr);
16365 }
16366 ValueDecl *D = Res.first;
16367 if (!D)
16368 continue;
16369
16370 QualType Type = D->getType();
16371 auto *VD = dyn_cast<VarDecl>(D);
16372
16373 // OpenMP [2.14.4.2, Restrictions, p.2]
16374 // A list item that appears in a copyprivate clause may not appear in a
16375 // private or firstprivate clause on the single construct.
16376 if (!VD || !DSAStack->isThreadPrivate(VD)) {
16377 DSAStackTy::DSAVarData DVar =
16378 DSAStack->getTopDSA(D, /*FromParent=*/false);
16379 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
16380 DVar.RefExpr) {
16381 Diag(ELoc, diag::err_omp_wrong_dsa)
16382 << getOpenMPClauseName(DVar.CKind)
16383 << getOpenMPClauseName(OMPC_copyprivate);
16384 reportOriginalDsa(*this, DSAStack, D, DVar);
16385 continue;
16386 }
16387
16388 // OpenMP [2.11.4.2, Restrictions, p.1]
16389 // All list items that appear in a copyprivate clause must be either
16390 // threadprivate or private in the enclosing context.
16391 if (DVar.CKind == OMPC_unknown) {
16392 DVar = DSAStack->getImplicitDSA(D, false);
16393 if (DVar.CKind == OMPC_shared) {
16394 Diag(ELoc, diag::err_omp_required_access)
16395 << getOpenMPClauseName(OMPC_copyprivate)
16396 << "threadprivate or private in the enclosing context";
16397 reportOriginalDsa(*this, DSAStack, D, DVar);
16398 continue;
16399 }
16400 }
16401 }
16402
16403 // Variably modified types are not supported.
16404 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
16405 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
16406 << getOpenMPClauseName(OMPC_copyprivate) << Type
16407 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
16408 bool IsDecl =
16409 !VD ||
16410 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
16411 Diag(D->getLocation(),
16412 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16413 << D;
16414 continue;
16415 }
16416
16417 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
16418 // A variable of class type (or array thereof) that appears in a
16419 // copyin clause requires an accessible, unambiguous copy assignment
16420 // operator for the class type.
16421 Type = Context.getBaseElementType(Type.getNonReferenceType())
16422 .getUnqualifiedType();
16423 VarDecl *SrcVD =
16424 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
16425 D->hasAttrs() ? &D->getAttrs() : nullptr);
16426 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
16427 VarDecl *DstVD =
16428 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
16429 D->hasAttrs() ? &D->getAttrs() : nullptr);
16430 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
16431 ExprResult AssignmentOp = BuildBinOp(
16432 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
16433 if (AssignmentOp.isInvalid())
16434 continue;
16435 AssignmentOp =
16436 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
16437 if (AssignmentOp.isInvalid())
16438 continue;
16439
16440 // No need to mark vars as copyprivate, they are already threadprivate or
16441 // implicitly private.
16442 assert(VD || isOpenMPCapturedDecl(D));
16443 Vars.push_back(
16444 VD ? RefExpr->IgnoreParens()
16445 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
16446 SrcExprs.push_back(PseudoSrcExpr);
16447 DstExprs.push_back(PseudoDstExpr);
16448 AssignmentOps.push_back(AssignmentOp.get());
16449 }
16450
16451 if (Vars.empty())
16452 return nullptr;
16453
16454 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16455 Vars, SrcExprs, DstExprs, AssignmentOps);
16456}
16457
16458OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
16459 SourceLocation StartLoc,
16460 SourceLocation LParenLoc,
16461 SourceLocation EndLoc) {
16462 if (VarList.empty())
16463 return nullptr;
16464
16465 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
16466}
16467
16468/// Tries to find omp_depend_t. type.
16469static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
16470 bool Diagnose = true) {
16471 QualType OMPDependT = Stack->getOMPDependT();
16472 if (!OMPDependT.isNull())
16473 return true;
16474 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
16475 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
16476 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
16477 if (Diagnose)
16478 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
16479 return false;
16480 }
16481 Stack->setOMPDependT(PT.get());
16482 return true;
16483}
16484
16485OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
16486 SourceLocation LParenLoc,
16487 SourceLocation EndLoc) {
16488 if (!Depobj)
16489 return nullptr;
16490
16491 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack);
16492
16493 // OpenMP 5.0, 2.17.10.1 depobj Construct
16494 // depobj is an lvalue expression of type omp_depend_t.
16495 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
16496 !Depobj->isInstantiationDependent() &&
16497 !Depobj->containsUnexpandedParameterPack() &&
16498 (OMPDependTFound &&
16499 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(),
16500 /*CompareUnqualified=*/true))) {
16501 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
16502 << 0 << Depobj->getType() << Depobj->getSourceRange();
16503 }
16504
16505 if (!Depobj->isLValue()) {
16506 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
16507 << 1 << Depobj->getSourceRange();
16508 }
16509
16510 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
16511}
16512
16513OMPClause *
16514Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind,
16515 SourceLocation DepLoc, SourceLocation ColonLoc,
16516 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
16517 SourceLocation LParenLoc, SourceLocation EndLoc) {
16518 if (DSAStack->getCurrentDirective() == OMPD_ordered &&
16519 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
16520 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
16521 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
16522 return nullptr;
16523 }
16524 if ((DSAStack->getCurrentDirective() != OMPD_ordered ||
16525 DSAStack->getCurrentDirective() == OMPD_depobj) &&
16526 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
16527 DepKind == OMPC_DEPEND_sink ||
16528 ((LangOpts.OpenMP < 50 ||
16529 DSAStack->getCurrentDirective() == OMPD_depobj) &&
16530 DepKind == OMPC_DEPEND_depobj))) {
16531 SmallVector<unsigned, 3> Except;
16532 Except.push_back(OMPC_DEPEND_source);
16533 Except.push_back(OMPC_DEPEND_sink);
16534 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj)
16535 Except.push_back(OMPC_DEPEND_depobj);
16536 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
16537 ? "depend modifier(iterator) or "
16538 : "";
16539 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
16540 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
16541 /*Last=*/OMPC_DEPEND_unknown,
16542 Except)
16543 << getOpenMPClauseName(OMPC_depend);
16544 return nullptr;
16545 }
16546 if (DepModifier &&
16547 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
16548 Diag(DepModifier->getExprLoc(),
16549 diag::err_omp_depend_sink_source_with_modifier);
16550 return nullptr;
16551 }
16552 if (DepModifier &&
16553 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
16554 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
16555
16556 SmallVector<Expr *, 8> Vars;
16557 DSAStackTy::OperatorOffsetTy OpsOffs;
16558 llvm::APSInt DepCounter(/*BitWidth=*/32);
16559 llvm::APSInt TotalDepCount(/*BitWidth=*/32);
16560 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
16561 if (const Expr *OrderedCountExpr =
16562 DSAStack->getParentOrderedRegionParam().first) {
16563 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
16564 TotalDepCount.setIsUnsigned(/*Val=*/true);
16565 }
16566 }
16567 for (Expr *RefExpr : VarList) {
16568 assert(RefExpr && "NULL expr in OpenMP shared clause.");
16569 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
16570 // It will be analyzed later.
16571 Vars.push_back(RefExpr);
16572 continue;
16573 }
16574
16575 SourceLocation ELoc = RefExpr->getExprLoc();
16576 Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
16577 if (DepKind == OMPC_DEPEND_sink) {
16578 if (DSAStack->getParentOrderedRegionParam().first &&
16579 DepCounter >= TotalDepCount) {
16580 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
16581 continue;
16582 }
16583 ++DepCounter;
16584 // OpenMP [2.13.9, Summary]
16585 // depend(dependence-type : vec), where dependence-type is:
16586 // 'sink' and where vec is the iteration vector, which has the form:
16587 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
16588 // where n is the value specified by the ordered clause in the loop
16589 // directive, xi denotes the loop iteration variable of the i-th nested
16590 // loop associated with the loop directive, and di is a constant
16591 // non-negative integer.
16592 if (CurContext->isDependentContext()) {
16593 // It will be analyzed later.
16594 Vars.push_back(RefExpr);
16595 continue;
16596 }
16597 SimpleExpr = SimpleExpr->IgnoreImplicit();
16598 OverloadedOperatorKind OOK = OO_None;
16599 SourceLocation OOLoc;
16600 Expr *LHS = SimpleExpr;
16601 Expr *RHS = nullptr;
16602 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
16603 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
16604 OOLoc = BO->getOperatorLoc();
16605 LHS = BO->getLHS()->IgnoreParenImpCasts();
16606 RHS = BO->getRHS()->IgnoreParenImpCasts();
16607 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
16608 OOK = OCE->getOperator();
16609 OOLoc = OCE->getOperatorLoc();
16610 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
16611 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
16612 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
16613 OOK = MCE->getMethodDecl()
16614 ->getNameInfo()
16615 .getName()
16616 .getCXXOverloadedOperator();
16617 OOLoc = MCE->getCallee()->getExprLoc();
16618 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
16619 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
16620 }
16621 SourceLocation ELoc;
16622 SourceRange ERange;
16623 auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
16624 if (Res.second) {
16625 // It will be analyzed later.
16626 Vars.push_back(RefExpr);
16627 }
16628 ValueDecl *D = Res.first;
16629 if (!D)
16630 continue;
16631
16632 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
16633 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
16634 continue;
16635 }
16636 if (RHS) {
16637 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
16638 RHS, OMPC_depend, /*StrictlyPositive=*/false);
16639 if (RHSRes.isInvalid())
16640 continue;
16641 }
16642 if (!CurContext->isDependentContext() &&
16643 DSAStack->getParentOrderedRegionParam().first &&
16644 DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
16645 const ValueDecl *VD =
16646 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
16647 if (VD)
16648 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
16649 << 1 << VD;
16650 else
16651 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
16652 continue;
16653 }
16654 OpsOffs.emplace_back(RHS, OOK);
16655 } else {
16656 bool OMPDependTFound = LangOpts.OpenMP >= 50;
16657 if (OMPDependTFound)
16658 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack,
16659 DepKind == OMPC_DEPEND_depobj);
16660 if (DepKind == OMPC_DEPEND_depobj) {
16661 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
16662 // List items used in depend clauses with the depobj dependence type
16663 // must be expressions of the omp_depend_t type.
16664 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
16665 !RefExpr->isInstantiationDependent() &&
16666 !RefExpr->containsUnexpandedParameterPack() &&
16667 (OMPDependTFound &&
16668 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(),
16669 RefExpr->getType()))) {
16670 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
16671 << 0 << RefExpr->getType() << RefExpr->getSourceRange();
16672 continue;
16673 }
16674 if (!RefExpr->isLValue()) {
16675 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
16676 << 1 << RefExpr->getType() << RefExpr->getSourceRange();
16677 continue;
16678 }
16679 } else {
16680 // OpenMP 5.0 [2.17.11, Restrictions]
16681 // List items used in depend clauses cannot be zero-length array
16682 // sections.
16683 QualType ExprTy = RefExpr->getType().getNonReferenceType();
16684 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
16685 if (OASE) {
16686 QualType BaseType =
16687 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
16688 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
16689 ExprTy = ATy->getElementType();
16690 else
16691 ExprTy = BaseType->getPointeeType();
16692 ExprTy = ExprTy.getNonReferenceType();
16693 const Expr *Length = OASE->getLength();
16694 Expr::EvalResult Result;
16695 if (Length && !Length->isValueDependent() &&
16696 Length->EvaluateAsInt(Result, Context) &&
16697 Result.Val.getInt().isNullValue()) {
16698 Diag(ELoc,
16699 diag::err_omp_depend_zero_length_array_section_not_allowed)
16700 << SimpleExpr->getSourceRange();
16701 continue;
16702 }
16703 }
16704
16705 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
16706 // List items used in depend clauses with the in, out, inout or
16707 // mutexinoutset dependence types cannot be expressions of the
16708 // omp_depend_t type.
16709 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
16710 !RefExpr->isInstantiationDependent() &&
16711 !RefExpr->containsUnexpandedParameterPack() &&
16712 (OMPDependTFound &&
16713 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) {
16714 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16715 << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1
16716 << RefExpr->getSourceRange();
16717 continue;
16718 }
16719
16720 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
16721 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
16722 (ASE && !ASE->getBase()->isTypeDependent() &&
16723 !ASE->getBase()
16724 ->getType()
16725 .getNonReferenceType()
16726 ->isPointerType() &&
16727 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
16728 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16729 << (LangOpts.OpenMP >= 50 ? 1 : 0)
16730 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
16731 continue;
16732 }
16733
16734 ExprResult Res;
16735 {
16736 Sema::TentativeAnalysisScope Trap(*this);
16737 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
16738 RefExpr->IgnoreParenImpCasts());
16739 }
16740 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
16741 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
16742 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16743 << (LangOpts.OpenMP >= 50 ? 1 : 0)
16744 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
16745 continue;
16746 }
16747 }
16748 }
16749 Vars.push_back(RefExpr->IgnoreParenImpCasts());
16750 }
16751
16752 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
16753 TotalDepCount > VarList.size() &&
16754 DSAStack->getParentOrderedRegionParam().first &&
16755 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
16756 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
16757 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
16758 }
16759 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
16760 Vars.empty())
16761 return nullptr;
16762
16763 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16764 DepModifier, DepKind, DepLoc, ColonLoc,
16765 Vars, TotalDepCount.getZExtValue());
16766 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
16767 DSAStack->isParentOrderedRegion())
16768 DSAStack->addDoacrossDependClause(C, OpsOffs);
16769 return C;
16770}
16771
16772OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
16773 Expr *Device, SourceLocation StartLoc,
16774 SourceLocation LParenLoc,
16775 SourceLocation ModifierLoc,
16776 SourceLocation EndLoc) {
16777 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&
16778 "Unexpected device modifier in OpenMP < 50.");
16779
16780 bool ErrorFound = false;
16781 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
16782 std::string Values =
16783 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
16784 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
16785 << Values << getOpenMPClauseName(OMPC_device);
16786 ErrorFound = true;
16787 }
16788
16789 Expr *ValExpr = Device;
16790 Stmt *HelperValStmt = nullptr;
16791
16792 // OpenMP [2.9.1, Restrictions]
16793 // The device expression must evaluate to a non-negative integer value.
16794 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
16795 /*StrictlyPositive=*/false) ||
16796 ErrorFound;
16797 if (ErrorFound)
16798 return nullptr;
16799
16800 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16801 OpenMPDirectiveKind CaptureRegion =
16802 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
16803 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16804 ValExpr = MakeFullExpr(ValExpr).get();
16805 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16806 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16807 HelperValStmt = buildPreInits(Context, Captures);
16808 }
16809
16810 return new (Context)
16811 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
16812 LParenLoc, ModifierLoc, EndLoc);
16813}
16814
16815static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
16816 DSAStackTy *Stack, QualType QTy,
16817 bool FullCheck = true) {
16818 NamedDecl *ND;
16819 if (QTy->isIncompleteType(&ND)) {
16820 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
16821 return false;
16822 }
16823 if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
16824 !QTy.isTriviallyCopyableType(SemaRef.Context))
16825 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
16826 return true;
16827}
16828
16829/// Return true if it can be proven that the provided array expression
16830/// (array section or array subscript) does NOT specify the whole size of the
16831/// array whose base type is \a BaseQTy.
16832static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
16833 const Expr *E,
16834 QualType BaseQTy) {
16835 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
16836
16837 // If this is an array subscript, it refers to the whole size if the size of
16838 // the dimension is constant and equals 1. Also, an array section assumes the
16839 // format of an array subscript if no colon is used.
16840 if (isa<ArraySubscriptExpr>(E) ||
16841 (OASE && OASE->getColonLocFirst().isInvalid())) {
16842 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
16843 return ATy->getSize().getSExtValue() != 1;
16844 // Size can't be evaluated statically.
16845 return false;
16846 }
16847
16848 assert(OASE && "Expecting array section if not an array subscript.");
16849 const Expr *LowerBound = OASE->getLowerBound();
16850 const Expr *Length = OASE->getLength();
16851
16852 // If there is a lower bound that does not evaluates to zero, we are not
16853 // covering the whole dimension.
16854 if (LowerBound) {
16855 Expr::EvalResult Result;
16856 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
16857 return false; // Can't get the integer value as a constant.
16858
16859 llvm::APSInt ConstLowerBound = Result.Val.getInt();
16860 if (ConstLowerBound.getSExtValue())
16861 return true;
16862 }
16863
16864 // If we don't have a length we covering the whole dimension.
16865 if (!Length)
16866 return false;
16867
16868 // If the base is a pointer, we don't have a way to get the size of the
16869 // pointee.
16870 if (BaseQTy->isPointerType())
16871 return false;
16872
16873 // We can only check if the length is the same as the size of the dimension
16874 // if we have a constant array.
16875 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
16876 if (!CATy)
16877 return false;
16878
16879 Expr::EvalResult Result;
16880 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
16881 return false; // Can't get the integer value as a constant.
16882
16883 llvm::APSInt ConstLength = Result.Val.getInt();
16884 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
16885}
16886
16887// Return true if it can be proven that the provided array expression (array
16888// section or array subscript) does NOT specify a single element of the array
16889// whose base type is \a BaseQTy.
16890static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
16891 const Expr *E,
16892 QualType BaseQTy) {
16893 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
16894
16895 // An array subscript always refer to a single element. Also, an array section
16896 // assumes the format of an array subscript if no colon is used.
16897 if (isa<ArraySubscriptExpr>(E) ||
16898 (OASE && OASE->getColonLocFirst().isInvalid()))
16899 return false;
16900
16901 assert(OASE && "Expecting array section if not an array subscript.");
16902 const Expr *Length = OASE->getLength();
16903
16904 // If we don't have a length we have to check if the array has unitary size
16905 // for this dimension. Also, we should always expect a length if the base type
16906 // is pointer.
16907 if (!Length) {
16908 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
16909 return ATy->getSize().getSExtValue() != 1;
16910 // We cannot assume anything.
16911 return false;
16912 }
16913
16914 // Check if the length evaluates to 1.
16915 Expr::EvalResult Result;
16916 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
16917 return false; // Can't get the integer value as a constant.
16918
16919 llvm::APSInt ConstLength = Result.Val.getInt();
16920 return ConstLength.getSExtValue() != 1;
16921}
16922
16923// The base of elements of list in a map clause have to be either:
16924// - a reference to variable or field.
16925// - a member expression.
16926// - an array expression.
16927//
16928// E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
16929// reference to 'r'.
16930//
16931// If we have:
16932//
16933// struct SS {
16934// Bla S;
16935// foo() {
16936// #pragma omp target map (S.Arr[:12]);
16937// }
16938// }
16939//
16940// We want to retrieve the member expression 'this->S';
16941
16942// OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
16943// If a list item is an array section, it must specify contiguous storage.
16944//
16945// For this restriction it is sufficient that we make sure only references
16946// to variables or fields and array expressions, and that no array sections
16947// exist except in the rightmost expression (unless they cover the whole
16948// dimension of the array). E.g. these would be invalid:
16949//
16950// r.ArrS[3:5].Arr[6:7]
16951//
16952// r.ArrS[3:5].x
16953//
16954// but these would be valid:
16955// r.ArrS[3].Arr[6:7]
16956//
16957// r.ArrS[3].x
16958namespace {
16959class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
16960 Sema &SemaRef;
16961 OpenMPClauseKind CKind = OMPC_unknown;
16962 OpenMPDirectiveKind DKind = OMPD_unknown;
16963 OMPClauseMappableExprCommon::MappableExprComponentList &Components;
16964 bool IsNonContiguous = false;
16965 bool NoDiagnose = false;
16966 const Expr *RelevantExpr = nullptr;
16967 bool AllowUnitySizeArraySection = true;
16968 bool AllowWholeSizeArraySection = true;
16969 bool AllowAnotherPtr = true;
16970 SourceLocation ELoc;
16971 SourceRange ERange;
16972
16973 void emitErrorMsg() {
16974 // If nothing else worked, this is not a valid map clause expression.
16975 if (SemaRef.getLangOpts().OpenMP < 50) {
16976 SemaRef.Diag(ELoc,
16977 diag::err_omp_expected_named_var_member_or_array_expression)
16978 << ERange;
16979 } else {
16980 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
16981 << getOpenMPClauseName(CKind) << ERange;
16982 }
16983 }
16984
16985public:
16986 bool VisitDeclRefExpr(DeclRefExpr *DRE) {
16987 if (!isa<VarDecl>(DRE->getDecl())) {
16988 emitErrorMsg();
16989 return false;
16990 }
16991 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
16992 RelevantExpr = DRE;
16993 // Record the component.
16994 Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
16995 return true;
16996 }
16997
16998 bool VisitMemberExpr(MemberExpr *ME) {
16999 Expr *E = ME;
17000 Expr *BaseE = ME->getBase()->IgnoreParenCasts();
17001
17002 if (isa<CXXThisExpr>(BaseE)) {
17003 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
17004 // We found a base expression: this->Val.
17005 RelevantExpr = ME;
17006 } else {
17007 E = BaseE;
17008 }
17009
17010 if (!isa<FieldDecl>(ME->getMemberDecl())) {
17011 if (!NoDiagnose) {
17012 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
17013 << ME->getSourceRange();
17014 return false;
17015 }
17016 if (RelevantExpr)
17017 return false;
17018 return Visit(E);
17019 }
17020
17021 auto *FD = cast<FieldDecl>(ME->getMemberDecl());
17022
17023 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
17024 // A bit-field cannot appear in a map clause.
17025 //
17026 if (FD->isBitField()) {
17027 if (!NoDiagnose) {
17028 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
17029 << ME->getSourceRange() << getOpenMPClauseName(CKind);
17030 return false;
17031 }
17032 if (RelevantExpr)
17033 return false;
17034 return Visit(E);
17035 }
17036
17037 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17038 // If the type of a list item is a reference to a type T then the type
17039 // will be considered to be T for all purposes of this clause.
17040 QualType CurType = BaseE->getType().getNonReferenceType();
17041
17042 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
17043 // A list item cannot be a variable that is a member of a structure with
17044 // a union type.
17045 //
17046 if (CurType->isUnionType()) {
17047 if (!NoDiagnose) {
17048 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
17049 << ME->getSourceRange();
17050 return false;
17051 }
17052 return RelevantExpr || Visit(E);
17053 }
17054
17055 // If we got a member expression, we should not expect any array section
17056 // before that:
17057 //
17058 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
17059 // If a list item is an element of a structure, only the rightmost symbol
17060 // of the variable reference can be an array section.
17061 //
17062 AllowUnitySizeArraySection = false;
17063 AllowWholeSizeArraySection = false;
17064
17065 // Record the component.
17066 Components.emplace_back(ME, FD, IsNonContiguous);
17067 return RelevantExpr || Visit(E);
17068 }
17069
17070 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
17071 Expr *E = AE->getBase()->IgnoreParenImpCasts();
17072
17073 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
17074 if (!NoDiagnose) {
17075 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
17076 << 0 << AE->getSourceRange();
17077 return false;
17078 }
17079 return RelevantExpr || Visit(E);
17080 }
17081
17082 // If we got an array subscript that express the whole dimension we
17083 // can have any array expressions before. If it only expressing part of
17084 // the dimension, we can only have unitary-size array expressions.
17085 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE,
17086 E->getType()))
17087 AllowWholeSizeArraySection = false;
17088
17089 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
17090 Expr::EvalResult Result;
17091 if (!AE->getIdx()->isValueDependent() &&
17092 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
17093 !Result.Val.getInt().isNullValue()) {
17094 SemaRef.Diag(AE->getIdx()->getExprLoc(),
17095 diag::err_omp_invalid_map_this_expr);
17096 SemaRef.Diag(AE->getIdx()->getExprLoc(),
17097 diag::note_omp_invalid_subscript_on_this_ptr_map);
17098 }
17099 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
17100 RelevantExpr = TE;
17101 }
17102
17103 // Record the component - we don't have any declaration associated.
17104 Components.emplace_back(AE, nullptr, IsNonContiguous);
17105
17106 return RelevantExpr || Visit(E);
17107 }
17108
17109 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
17110 assert(!NoDiagnose && "Array sections cannot be implicitly mapped.");
17111 Expr *E = OASE->getBase()->IgnoreParenImpCasts();
17112 QualType CurType =
17113 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
17114
17115 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17116 // If the type of a list item is a reference to a type T then the type
17117 // will be considered to be T for all purposes of this clause.
17118 if (CurType->isReferenceType())
17119 CurType = CurType->getPointeeType();
17120
17121 bool IsPointer = CurType->isAnyPointerType();
17122
17123 if (!IsPointer && !CurType->isArrayType()) {
17124 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
17125 << 0 << OASE->getSourceRange();
17126 return false;
17127 }
17128
17129 bool NotWhole =
17130 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
17131 bool NotUnity =
17132 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
17133
17134 if (AllowWholeSizeArraySection) {
17135 // Any array section is currently allowed. Allowing a whole size array
17136 // section implies allowing a unity array section as well.
17137 //
17138 // If this array section refers to the whole dimension we can still
17139 // accept other array sections before this one, except if the base is a
17140 // pointer. Otherwise, only unitary sections are accepted.
17141 if (NotWhole || IsPointer)
17142 AllowWholeSizeArraySection = false;
17143 } else if (DKind == OMPD_target_update &&
17144 SemaRef.getLangOpts().OpenMP >= 50) {
17145 if (IsPointer && !AllowAnotherPtr)
17146 SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
17147 << /*array of unknown bound */ 1;
17148 else
17149 IsNonContiguous = true;
17150 } else if (AllowUnitySizeArraySection && NotUnity) {
17151 // A unity or whole array section is not allowed and that is not
17152 // compatible with the properties of the current array section.
17153 SemaRef.Diag(
17154 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
17155 << OASE->getSourceRange();
17156 return false;
17157 }
17158
17159 if (IsPointer)
17160 AllowAnotherPtr = false;
17161
17162 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
17163 Expr::EvalResult ResultR;
17164 Expr::EvalResult ResultL;
17165 if (!OASE->getLength()->isValueDependent() &&
17166 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
17167 !ResultR.Val.getInt().isOneValue()) {
17168 SemaRef.Diag(OASE->getLength()->getExprLoc(),
17169 diag::err_omp_invalid_map_this_expr);
17170 SemaRef.Diag(OASE->getLength()->getExprLoc(),
17171 diag::note_omp_invalid_length_on_this_ptr_mapping);
17172 }
17173 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
17174 OASE->getLowerBound()->EvaluateAsInt(ResultL,
17175 SemaRef.getASTContext()) &&
17176 !ResultL.Val.getInt().isNullValue()) {
17177 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
17178 diag::err_omp_invalid_map_this_expr);
17179 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
17180 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
17181 }
17182 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
17183 RelevantExpr = TE;
17184 }
17185
17186 // Record the component - we don't have any declaration associated.
17187 Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
17188 return RelevantExpr || Visit(E);
17189 }
17190 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
17191 Expr *Base = E->getBase();
17192
17193 // Record the component - we don't have any declaration associated.
17194 Components.emplace_back(E, nullptr, IsNonContiguous);
17195
17196 return Visit(Base->IgnoreParenImpCasts());
17197 }
17198
17199 bool VisitUnaryOperator(UnaryOperator *UO) {
17200 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
17201 UO->getOpcode() != UO_Deref) {
17202 emitErrorMsg();
17203 return false;
17204 }
17205 if (!RelevantExpr) {
17206 // Record the component if haven't found base decl.
17207 Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
17208 }
17209 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
17210 }
17211 bool VisitBinaryOperator(BinaryOperator *BO) {
17212 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
17213 emitErrorMsg();
17214 return false;
17215 }
17216
17217 // Pointer arithmetic is the only thing we expect to happen here so after we
17218 // make sure the binary operator is a pointer type, the we only thing need
17219 // to to is to visit the subtree that has the same type as root (so that we
17220 // know the other subtree is just an offset)
17221 Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
17222 Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
17223 Components.emplace_back(BO, nullptr, false);
17224 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||
17225 RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&
17226 "Either LHS or RHS have base decl inside");
17227 if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
17228 return RelevantExpr || Visit(LE);
17229 return RelevantExpr || Visit(RE);
17230 }
17231 bool VisitCXXThisExpr(CXXThisExpr *CTE) {
17232 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
17233 RelevantExpr = CTE;
17234 Components.emplace_back(CTE, nullptr, IsNonContiguous);
17235 return true;
17236 }
17237 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
17238 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
17239 Components.emplace_back(COCE, nullptr, IsNonContiguous);
17240 return true;
17241 }
17242 bool VisitStmt(Stmt *) {
17243 emitErrorMsg();
17244 return false;
17245 }
17246 const Expr *getFoundBase() const {
17247 return RelevantExpr;
17248 }
17249 explicit MapBaseChecker(
17250 Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
17251 OMPClauseMappableExprCommon::MappableExprComponentList &Components,
17252 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
17253 : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
17254 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
17255};
17256} // namespace
17257
17258/// Return the expression of the base of the mappable expression or null if it
17259/// cannot be determined and do all the necessary checks to see if the expression
17260/// is valid as a standalone mappable expression. In the process, record all the
17261/// components of the expression.
17262static const Expr *checkMapClauseExpressionBase(
17263 Sema &SemaRef, Expr *E,
17264 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
17265 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
17266 SourceLocation ELoc = E->getExprLoc();
17267 SourceRange ERange = E->getSourceRange();
17268 MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
17269 ERange);
17270 if (Checker.Visit(E->IgnoreParens())) {
17271 // Check if the highest dimension array section has length specified
17272 if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
17273 (CKind == OMPC_to || CKind == OMPC_from)) {
17274 auto CI = CurComponents.rbegin();
17275 auto CE = CurComponents.rend();
17276 for (; CI != CE; ++CI) {
17277 const auto *OASE =
17278 dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
17279 if (!OASE)
17280 continue;
17281 if (OASE && OASE->getLength())
17282 break;
17283 SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
17284 << ERange;
17285 }
17286 }
17287 return Checker.getFoundBase();
17288 }
17289 return nullptr;
17290}
17291
17292// Return true if expression E associated with value VD has conflicts with other
17293// map information.
17294static bool checkMapConflicts(
17295 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
17296 bool CurrentRegionOnly,
17297 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
17298 OpenMPClauseKind CKind) {
17299 assert(VD && E);
17300 SourceLocation ELoc = E->getExprLoc();
17301 SourceRange ERange = E->getSourceRange();
17302
17303 // In order to easily check the conflicts we need to match each component of
17304 // the expression under test with the components of the expressions that are
17305 // already in the stack.
17306
17307 assert(!CurComponents.empty() && "Map clause expression with no components!");
17308 assert(CurComponents.back().getAssociatedDeclaration() == VD &&
17309 "Map clause expression with unexpected base!");
17310
17311 // Variables to help detecting enclosing problems in data environment nests.
17312 bool IsEnclosedByDataEnvironmentExpr = false;
17313 const Expr *EnclosingExpr = nullptr;
17314
17315 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
17316 VD, CurrentRegionOnly,
17317 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
17318 ERange, CKind, &EnclosingExpr,
17319 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
17320 StackComponents,
17321 OpenMPClauseKind) {
17322 assert(!StackComponents.empty() &&
17323 "Map clause expression with no components!");
17324 assert(StackComponents.back().getAssociatedDeclaration() == VD &&
17325 "Map clause expression with unexpected base!");
17326 (void)VD;
17327
17328 // The whole expression in the stack.
17329 const Expr *RE = StackComponents.front().getAssociatedExpression();
17330
17331 // Expressions must start from the same base. Here we detect at which
17332 // point both expressions diverge from each other and see if we can
17333 // detect if the memory referred to both expressions is contiguous and
17334 // do not overlap.
17335 auto CI = CurComponents.rbegin();
17336 auto CE = CurComponents.rend();
17337 auto SI = StackComponents.rbegin();
17338 auto SE = StackComponents.rend();
17339 for (; CI != CE && SI != SE; ++CI, ++SI) {
17340
17341 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
17342 // At most one list item can be an array item derived from a given
17343 // variable in map clauses of the same construct.
17344 if (CurrentRegionOnly &&
17345 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
17346 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
17347 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
17348 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
17349 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
17350 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
17351 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
17352 diag::err_omp_multiple_array_items_in_map_clause)
17353 << CI->getAssociatedExpression()->getSourceRange();
17354 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
17355 diag::note_used_here)
17356 << SI->getAssociatedExpression()->getSourceRange();
17357 return true;
17358 }
17359
17360 // Do both expressions have the same kind?
17361 if (CI->getAssociatedExpression()->getStmtClass() !=
17362 SI->getAssociatedExpression()->getStmtClass())
17363 break;
17364
17365 // Are we dealing with different variables/fields?
17366 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
17367 break;
17368 }
17369 // Check if the extra components of the expressions in the enclosing
17370 // data environment are redundant for the current base declaration.
17371 // If they are, the maps completely overlap, which is legal.
17372 for (; SI != SE; ++SI) {
17373 QualType Type;
17374 if (const auto *ASE =
17375 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
17376 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
17377 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
17378 SI->getAssociatedExpression())) {
17379 const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
17380 Type =
17381 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
17382 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
17383 SI->getAssociatedExpression())) {
17384 Type = OASE->getBase()->getType()->getPointeeType();
17385 }
17386 if (Type.isNull() || Type->isAnyPointerType() ||
17387 checkArrayExpressionDoesNotReferToWholeSize(
17388 SemaRef, SI->getAssociatedExpression(), Type))
17389 break;
17390 }
17391
17392 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
17393 // List items of map clauses in the same construct must not share
17394 // original storage.
17395 //
17396 // If the expressions are exactly the same or one is a subset of the
17397 // other, it means they are sharing storage.
17398 if (CI == CE && SI == SE) {
17399 if (CurrentRegionOnly) {
17400 if (CKind == OMPC_map) {
17401 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
17402 } else {
17403 assert(CKind == OMPC_to || CKind == OMPC_from);
17404 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
17405 << ERange;
17406 }
17407 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17408 << RE->getSourceRange();
17409 return true;
17410 }
17411 // If we find the same expression in the enclosing data environment,
17412 // that is legal.
17413 IsEnclosedByDataEnvironmentExpr = true;
17414 return false;
17415 }
17416
17417 QualType DerivedType =
17418 std::prev(CI)->getAssociatedDeclaration()->getType();
17419 SourceLocation DerivedLoc =
17420 std::prev(CI)->getAssociatedExpression()->getExprLoc();
17421
17422 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17423 // If the type of a list item is a reference to a type T then the type
17424 // will be considered to be T for all purposes of this clause.
17425 DerivedType = DerivedType.getNonReferenceType();
17426
17427 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
17428 // A variable for which the type is pointer and an array section
17429 // derived from that variable must not appear as list items of map
17430 // clauses of the same construct.
17431 //
17432 // Also, cover one of the cases in:
17433 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
17434 // If any part of the original storage of a list item has corresponding
17435 // storage in the device data environment, all of the original storage
17436 // must have corresponding storage in the device data environment.
17437 //
17438 if (DerivedType->isAnyPointerType()) {
17439 if (CI == CE || SI == SE) {
17440 SemaRef.Diag(
17441 DerivedLoc,
17442 diag::err_omp_pointer_mapped_along_with_derived_section)
17443 << DerivedLoc;
17444 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17445 << RE->getSourceRange();
17446 return true;
17447 }
17448 if (CI->getAssociatedExpression()->getStmtClass() !=
17449 SI->getAssociatedExpression()->getStmtClass() ||
17450 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
17451 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
17452 assert(CI != CE && SI != SE);
17453 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
17454 << DerivedLoc;
17455 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17456 << RE->getSourceRange();
17457 return true;
17458 }
17459 }
17460
17461 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
17462 // List items of map clauses in the same construct must not share
17463 // original storage.
17464 //
17465 // An expression is a subset of the other.
17466 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
17467 if (CKind == OMPC_map) {
17468 if (CI != CE || SI != SE) {
17469 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
17470 // a pointer.
17471 auto Begin =
17472 CI != CE ? CurComponents.begin() : StackComponents.begin();
17473 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
17474 auto It = Begin;
17475 while (It != End && !It->getAssociatedDeclaration())
17476 std::advance(It, 1);
17477 assert(It != End &&
17478 "Expected at least one component with the declaration.");
17479 if (It != Begin && It->getAssociatedDeclaration()
17480 ->getType()
17481 .getCanonicalType()
17482 ->isAnyPointerType()) {
17483 IsEnclosedByDataEnvironmentExpr = false;
17484 EnclosingExpr = nullptr;
17485 return false;
17486 }
17487 }
17488 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
17489 } else {
17490 assert(CKind == OMPC_to || CKind == OMPC_from);
17491 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
17492 << ERange;
17493 }
17494 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17495 << RE->getSourceRange();
17496 return true;
17497 }
17498
17499 // The current expression uses the same base as other expression in the
17500 // data environment but does not contain it completely.
17501 if (!CurrentRegionOnly && SI != SE)
17502 EnclosingExpr = RE;
17503
17504 // The current expression is a subset of the expression in the data
17505 // environment.
17506 IsEnclosedByDataEnvironmentExpr |=
17507 (!CurrentRegionOnly && CI != CE && SI == SE);
17508
17509 return false;
17510 });
17511
17512 if (CurrentRegionOnly)
17513 return FoundError;
17514
17515 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
17516 // If any part of the original storage of a list item has corresponding
17517 // storage in the device data environment, all of the original storage must
17518 // have corresponding storage in the device data environment.
17519 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
17520 // If a list item is an element of a structure, and a different element of
17521 // the structure has a corresponding list item in the device data environment
17522 // prior to a task encountering the construct associated with the map clause,
17523 // then the list item must also have a corresponding list item in the device
17524 // data environment prior to the task encountering the construct.
17525 //
17526 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
17527 SemaRef.Diag(ELoc,
17528 diag::err_omp_original_storage_is_shared_and_does_not_contain)
17529 << ERange;
17530 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
17531 << EnclosingExpr->getSourceRange();
17532 return true;
17533 }
17534
17535 return FoundError;
17536}
17537
17538// Look up the user-defined mapper given the mapper name and mapped type, and
17539// build a reference to it.
17540static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
17541 CXXScopeSpec &MapperIdScopeSpec,
17542 const DeclarationNameInfo &MapperId,
17543 QualType Type,
17544 Expr *UnresolvedMapper) {
17545 if (MapperIdScopeSpec.isInvalid())
17546 return ExprError();
17547 // Get the actual type for the array type.
17548 if (Type->isArrayType()) {
17549 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type");
17550 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
17551 }
17552 // Find all user-defined mappers with the given MapperId.
17553 SmallVector<UnresolvedSet<8>, 4> Lookups;
17554 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
17555 Lookup.suppressDiagnostics();
17556 if (S) {
17557 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
17558 NamedDecl *D = Lookup.getRepresentativeDecl();
17559 while (S && !S->isDeclScope(D))
17560 S = S->getParent();
17561 if (S)
17562 S = S->getParent();
17563 Lookups.emplace_back();
17564 Lookups.back().append(Lookup.begin(), Lookup.end());
17565 Lookup.clear();
17566 }
17567 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
17568 // Extract the user-defined mappers with the given MapperId.
17569 Lookups.push_back(UnresolvedSet<8>());
17570 for (NamedDecl *D : ULE->decls()) {
17571 auto *DMD = cast<OMPDeclareMapperDecl>(D);
17572 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
17573 Lookups.back().addDecl(DMD);
17574 }
17575 }
17576 // Defer the lookup for dependent types. The results will be passed through
17577 // UnresolvedMapper on instantiation.
17578 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
17579 Type->isInstantiationDependentType() ||
17580 Type->containsUnexpandedParameterPack() ||
17581 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
17582 return !D->isInvalidDecl() &&
17583 (D->getType()->isDependentType() ||
17584 D->getType()->isInstantiationDependentType() ||
17585 D->getType()->containsUnexpandedParameterPack());
17586 })) {
17587 UnresolvedSet<8> URS;
17588 for (const UnresolvedSet<8> &Set : Lookups) {
17589 if (Set.empty())
17590 continue;
17591 URS.append(Set.begin(), Set.end());
17592 }
17593 return UnresolvedLookupExpr::Create(
17594 SemaRef.Context, /*NamingClass=*/nullptr,
17595 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
17596 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
17597 }
17598 SourceLocation Loc = MapperId.getLoc();
17599 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
17600 // The type must be of struct, union or class type in C and C++
17601 if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
17602 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
17603 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
17604 return ExprError();
17605 }
17606 // Perform argument dependent lookup.
17607 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
17608 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
17609 // Return the first user-defined mapper with the desired type.
17610 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
17611 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
17612 if (!D->isInvalidDecl() &&
17613 SemaRef.Context.hasSameType(D->getType(), Type))
17614 return D;
17615 return nullptr;
17616 }))
17617 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
17618 // Find the first user-defined mapper with a type derived from the desired
17619 // type.
17620 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
17621 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
17622 if (!D->isInvalidDecl() &&
17623 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
17624 !Type.isMoreQualifiedThan(D->getType()))
17625 return D;
17626 return nullptr;
17627 })) {
17628 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
17629 /*DetectVirtual=*/false);
17630 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
17631 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
17632 VD->getType().getUnqualifiedType()))) {
17633 if (SemaRef.CheckBaseClassAccess(
17634 Loc, VD->getType(), Type, Paths.front(),
17635 /*DiagID=*/0) != Sema::AR_inaccessible) {
17636 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
17637 }
17638 }
17639 }
17640 }
17641 // Report error if a mapper is specified, but cannot be found.
17642 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
17643 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
17644 << Type << MapperId.getName();
17645 return ExprError();
17646 }
17647 return ExprEmpty();
17648}
17649
17650namespace {
17651// Utility struct that gathers all the related lists associated with a mappable
17652// expression.
17653struct MappableVarListInfo {
17654 // The list of expressions.
17655 ArrayRef<Expr *> VarList;
17656 // The list of processed expressions.
17657 SmallVector<Expr *, 16> ProcessedVarList;
17658 // The mappble components for each expression.
17659 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
17660 // The base declaration of the variable.
17661 SmallVector<ValueDecl *, 16> VarBaseDeclarations;
17662 // The reference to the user-defined mapper associated with every expression.
17663 SmallVector<Expr *, 16> UDMapperList;
17664
17665 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
17666 // We have a list of components and base declarations for each entry in the
17667 // variable list.
17668 VarComponents.reserve(VarList.size());
17669 VarBaseDeclarations.reserve(VarList.size());
17670 }
17671};
17672}
17673
17674// Check the validity of the provided variable list for the provided clause kind
17675// \a CKind. In the check process the valid expressions, mappable expression
17676// components, variables, and user-defined mappers are extracted and used to
17677// fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
17678// UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
17679// and \a MapperId are expected to be valid if the clause kind is 'map'.
17680static void checkMappableExpressionList(
17681 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
17682 MappableVarListInfo &MVLI, SourceLocation StartLoc,
17683 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
17684 ArrayRef<Expr *> UnresolvedMappers,
17685 OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
17686 bool IsMapTypeImplicit = false) {
17687 // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
17688 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
17689 "Unexpected clause kind with mappable expressions!");
17690
17691 // If the identifier of user-defined mapper is not specified, it is "default".
17692 // We do not change the actual name in this clause to distinguish whether a
17693 // mapper is specified explicitly, i.e., it is not explicitly specified when
17694 // MapperId.getName() is empty.
17695 if (!MapperId.getName() || MapperId.getName().isEmpty()) {
17696 auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
17697 MapperId.setName(DeclNames.getIdentifier(
17698 &SemaRef.getASTContext().Idents.get("default")));
17699 MapperId.setLoc(StartLoc);
17700 }
17701
17702 // Iterators to find the current unresolved mapper expression.
17703 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
17704 bool UpdateUMIt = false;
17705 Expr *UnresolvedMapper = nullptr;
17706
17707 // Keep track of the mappable components and base declarations in this clause.
17708 // Each entry in the list is going to have a list of components associated. We
17709 // record each set of the components so that we can build the clause later on.
17710 // In the end we should have the same amount of declarations and component
17711 // lists.
17712
17713 for (Expr *RE : MVLI.VarList) {
17714 assert(RE && "Null expr in omp to/from/map clause");
17715 SourceLocation ELoc = RE->getExprLoc();
17716
17717 // Find the current unresolved mapper expression.
17718 if (UpdateUMIt && UMIt != UMEnd) {
17719 UMIt++;
17720 assert(
17721 UMIt != UMEnd &&
17722 "Expect the size of UnresolvedMappers to match with that of VarList");
17723 }
17724 UpdateUMIt = true;
17725 if (UMIt != UMEnd)
17726 UnresolvedMapper = *UMIt;
17727
17728 const Expr *VE = RE->IgnoreParenLValueCasts();
17729
17730 if (VE->isValueDependent() || VE->isTypeDependent() ||
17731 VE->isInstantiationDependent() ||
17732 VE->containsUnexpandedParameterPack()) {
17733 // Try to find the associated user-defined mapper.
17734 ExprResult ER = buildUserDefinedMapperRef(
17735 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17736 VE->getType().getCanonicalType(), UnresolvedMapper);
17737 if (ER.isInvalid())
17738 continue;
17739 MVLI.UDMapperList.push_back(ER.get());
17740 // We can only analyze this information once the missing information is
17741 // resolved.
17742 MVLI.ProcessedVarList.push_back(RE);
17743 continue;
17744 }
17745
17746 Expr *SimpleExpr = RE->IgnoreParenCasts();
17747
17748 if (!RE->isLValue()) {
17749 if (SemaRef.getLangOpts().OpenMP < 50) {
17750 SemaRef.Diag(
17751 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
17752 << RE->getSourceRange();
17753 } else {
17754 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
17755 << getOpenMPClauseName(CKind) << RE->getSourceRange();
17756 }
17757 continue;
17758 }
17759
17760 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
17761 ValueDecl *CurDeclaration = nullptr;
17762
17763 // Obtain the array or member expression bases if required. Also, fill the
17764 // components array with all the components identified in the process.
17765 const Expr *BE = checkMapClauseExpressionBase(
17766 SemaRef, SimpleExpr, CurComponents, CKind, DSAS->getCurrentDirective(),
17767 /*NoDiagnose=*/false);
17768 if (!BE)
17769 continue;
17770
17771 assert(!CurComponents.empty() &&
17772 "Invalid mappable expression information.");
17773
17774 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
17775 // Add store "this" pointer to class in DSAStackTy for future checking
17776 DSAS->addMappedClassesQualTypes(TE->getType());
17777 // Try to find the associated user-defined mapper.
17778 ExprResult ER = buildUserDefinedMapperRef(
17779 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17780 VE->getType().getCanonicalType(), UnresolvedMapper);
17781 if (ER.isInvalid())
17782 continue;
17783 MVLI.UDMapperList.push_back(ER.get());
17784 // Skip restriction checking for variable or field declarations
17785 MVLI.ProcessedVarList.push_back(RE);
17786 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
17787 MVLI.VarComponents.back().append(CurComponents.begin(),
17788 CurComponents.end());
17789 MVLI.VarBaseDeclarations.push_back(nullptr);
17790 continue;
17791 }
17792
17793 // For the following checks, we rely on the base declaration which is
17794 // expected to be associated with the last component. The declaration is
17795 // expected to be a variable or a field (if 'this' is being mapped).
17796 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
17797 assert(CurDeclaration && "Null decl on map clause.");
17798 assert(
17799 CurDeclaration->isCanonicalDecl() &&
17800 "Expecting components to have associated only canonical declarations.");
17801
17802 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
17803 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
17804
17805 assert((VD || FD) && "Only variables or fields are expected here!");
17806 (void)FD;
17807
17808 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
17809 // threadprivate variables cannot appear in a map clause.
17810 // OpenMP 4.5 [2.10.5, target update Construct]
17811 // threadprivate variables cannot appear in a from clause.
17812 if (VD && DSAS->isThreadPrivate(VD)) {
17813 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
17814 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
17815 << getOpenMPClauseName(CKind);
17816 reportOriginalDsa(SemaRef, DSAS, VD, DVar);
17817 continue;
17818 }
17819
17820 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
17821 // A list item cannot appear in both a map clause and a data-sharing
17822 // attribute clause on the same construct.
17823
17824 // Check conflicts with other map clause expressions. We check the conflicts
17825 // with the current construct separately from the enclosing data
17826 // environment, because the restrictions are different. We only have to
17827 // check conflicts across regions for the map clauses.
17828 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
17829 /*CurrentRegionOnly=*/true, CurComponents, CKind))
17830 break;
17831 if (CKind == OMPC_map &&
17832 (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
17833 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
17834 /*CurrentRegionOnly=*/false, CurComponents, CKind))
17835 break;
17836
17837 // OpenMP 4.5 [2.10.5, target update Construct]
17838 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17839 // If the type of a list item is a reference to a type T then the type will
17840 // be considered to be T for all purposes of this clause.
17841 auto I = llvm::find_if(
17842 CurComponents,
17843 [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
17844 return MC.getAssociatedDeclaration();
17845 });
17846 assert(I != CurComponents.end() && "Null decl on map clause.");
17847 QualType Type;
17848 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
17849 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
17850 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
17851 if (ASE) {
17852 Type = ASE->getType().getNonReferenceType();
17853 } else if (OASE) {
17854 QualType BaseType =
17855 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
17856 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
17857 Type = ATy->getElementType();
17858 else
17859 Type = BaseType->getPointeeType();
17860 Type = Type.getNonReferenceType();
17861 } else if (OAShE) {
17862 Type = OAShE->getBase()->getType()->getPointeeType();
17863 } else {
17864 Type = VE->getType();
17865 }
17866
17867 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
17868 // A list item in a to or from clause must have a mappable type.
17869 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
17870 // A list item must have a mappable type.
17871 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
17872 DSAS, Type))
17873 continue;
17874
17875 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType();
17876
17877 if (CKind == OMPC_map) {
17878 // target enter data
17879 // OpenMP [2.10.2, Restrictions, p. 99]
17880 // A map-type must be specified in all map clauses and must be either
17881 // to or alloc.
17882 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
17883 if (DKind == OMPD_target_enter_data &&
17884 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
17885 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17886 << (IsMapTypeImplicit ? 1 : 0)
17887 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17888 << getOpenMPDirectiveName(DKind);
17889 continue;
17890 }
17891
17892 // target exit_data
17893 // OpenMP [2.10.3, Restrictions, p. 102]
17894 // A map-type must be specified in all map clauses and must be either
17895 // from, release, or delete.
17896 if (DKind == OMPD_target_exit_data &&
17897 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
17898 MapType == OMPC_MAP_delete)) {
17899 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17900 << (IsMapTypeImplicit ? 1 : 0)
17901 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17902 << getOpenMPDirectiveName(DKind);
17903 continue;
17904 }
17905
17906 // target, target data
17907 // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
17908 // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
17909 // A map-type in a map clause must be to, from, tofrom or alloc
17910 if ((DKind == OMPD_target_data ||
17911 isOpenMPTargetExecutionDirective(DKind)) &&
17912 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
17913 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
17914 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17915 << (IsMapTypeImplicit ? 1 : 0)
17916 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17917 << getOpenMPDirectiveName(DKind);
17918 continue;
17919 }
17920
17921 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
17922 // A list item cannot appear in both a map clause and a data-sharing
17923 // attribute clause on the same construct
17924 //
17925 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
17926 // A list item cannot appear in both a map clause and a data-sharing
17927 // attribute clause on the same construct unless the construct is a
17928 // combined construct.
17929 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
17930 isOpenMPTargetExecutionDirective(DKind)) ||
17931 DKind == OMPD_target)) {
17932 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
17933 if (isOpenMPPrivate(DVar.CKind)) {
17934 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
17935 << getOpenMPClauseName(DVar.CKind)
17936 << getOpenMPClauseName(OMPC_map)
17937 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
17938 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
17939 continue;
17940 }
17941 }
17942 }
17943
17944 // Try to find the associated user-defined mapper.
17945 ExprResult ER = buildUserDefinedMapperRef(
17946 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17947 Type.getCanonicalType(), UnresolvedMapper);
17948 if (ER.isInvalid())
17949 continue;
17950 MVLI.UDMapperList.push_back(ER.get());
17951
17952 // Save the current expression.
17953 MVLI.ProcessedVarList.push_back(RE);
17954
17955 // Store the components in the stack so that they can be used to check
17956 // against other clauses later on.
17957 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
17958 /*WhereFoundClauseKind=*/OMPC_map);
17959
17960 // Save the components and declaration to create the clause. For purposes of
17961 // the clause creation, any component list that has has base 'this' uses
17962 // null as base declaration.
17963 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
17964 MVLI.VarComponents.back().append(CurComponents.begin(),
17965 CurComponents.end());
17966 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
17967 : CurDeclaration);
17968 }
17969}
17970
17971OMPClause *Sema::ActOnOpenMPMapClause(
17972 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
17973 ArrayRef<SourceLocation> MapTypeModifiersLoc,
17974 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
17975 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
17976 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
17977 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
17978 OpenMPMapModifierKind Modifiers[] = {
17979 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
17980 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
17981 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
17982
17983 // Process map-type-modifiers, flag errors for duplicate modifiers.
17984 unsigned Count = 0;
17985 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
17986 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
17987 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
17988 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
17989 continue;
17990 }
17991 assert(Count < NumberOfOMPMapClauseModifiers &&
17992 "Modifiers exceed the allowed number of map type modifiers");
17993 Modifiers[Count] = MapTypeModifiers[I];
17994 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
17995 ++Count;
17996 }
17997
17998 MappableVarListInfo MVLI(VarList);
17999 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
18000 MapperIdScopeSpec, MapperId, UnresolvedMappers,
18001 MapType, IsMapTypeImplicit);
18002
18003 // We need to produce a map clause even if we don't have variables so that
18004 // other diagnostics related with non-existing map clauses are accurate.
18005 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
18006 MVLI.VarBaseDeclarations, MVLI.VarComponents,
18007 MVLI.UDMapperList, Modifiers, ModifiersLoc,
18008 MapperIdScopeSpec.getWithLocInContext(Context),
18009 MapperId, MapType, IsMapTypeImplicit, MapLoc);
18010}
18011
18012QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
18013 TypeResult ParsedType) {
18014 assert(ParsedType.isUsable());
18015
18016 QualType ReductionType = GetTypeFromParser(ParsedType.get());
18017 if (ReductionType.isNull())
18018 return QualType();
18019
18020 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
18021 // A type name in a declare reduction directive cannot be a function type, an
18022 // array type, a reference type, or a type qualified with const, volatile or
18023 // restrict.
18024 if (ReductionType.hasQualifiers()) {
18025 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
18026 return QualType();
18027 }
18028
18029 if (ReductionType->isFunctionType()) {
18030 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
18031 return QualType();
18032 }
18033 if (ReductionType->isReferenceType()) {
18034 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
18035 return QualType();
18036 }
18037 if (ReductionType->isArrayType()) {
18038 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
18039 return QualType();
18040 }
18041 return ReductionType;
18042}
18043
18044Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
18045 Scope *S, DeclContext *DC, DeclarationName Name,
18046 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
18047 AccessSpecifier AS, Decl *PrevDeclInScope) {
18048 SmallVector<Decl *, 8> Decls;
18049 Decls.reserve(ReductionTypes.size());
18050
18051 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
18052 forRedeclarationInCurContext());
18053 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
18054 // A reduction-identifier may not be re-declared in the current scope for the
18055 // same type or for a type that is compatible according to the base language
18056 // rules.
18057 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
18058 OMPDeclareReductionDecl *PrevDRD = nullptr;
18059 bool InCompoundScope = true;
18060 if (S != nullptr) {
18061 // Find previous declaration with the same name not referenced in other
18062 // declarations.
18063 FunctionScopeInfo *ParentFn = getEnclosingFunction();
18064 InCompoundScope =
18065 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
18066 LookupName(Lookup, S);
18067 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
18068 /*AllowInlineNamespace=*/false);
18069 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
18070 LookupResult::Filter Filter = Lookup.makeFilter();
18071 while (Filter.hasNext()) {
18072 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
18073 if (InCompoundScope) {
18074 auto I = UsedAsPrevious.find(PrevDecl);
18075 if (I == UsedAsPrevious.end())
18076 UsedAsPrevious[PrevDecl] = false;
18077 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
18078 UsedAsPrevious[D] = true;
18079 }
18080 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
18081 PrevDecl->getLocation();
18082 }
18083 Filter.done();
18084 if (InCompoundScope) {
18085 for (const auto &PrevData : UsedAsPrevious) {
18086 if (!PrevData.second) {
18087 PrevDRD = PrevData.first;
18088 break;
18089 }
18090 }
18091 }
18092 } else if (PrevDeclInScope != nullptr) {
18093 auto *PrevDRDInScope = PrevDRD =
18094 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
18095 do {
18096 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
18097 PrevDRDInScope->getLocation();
18098 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
18099 } while (PrevDRDInScope != nullptr);
18100 }
18101 for (const auto &TyData : ReductionTypes) {
18102 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
18103 bool Invalid = false;
18104 if (I != PreviousRedeclTypes.end()) {
18105 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
18106 << TyData.first;
18107 Diag(I->second, diag::note_previous_definition);
18108 Invalid = true;
18109 }
18110 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
18111 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
18112 Name, TyData.first, PrevDRD);
18113 DC->addDecl(DRD);
18114 DRD->setAccess(AS);
18115 Decls.push_back(DRD);
18116 if (Invalid)
18117 DRD->setInvalidDecl();
18118 else
18119 PrevDRD = DRD;
18120 }
18121
18122 return DeclGroupPtrTy::make(
18123 DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
18124}
18125
18126void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
18127 auto *DRD = cast<OMPDeclareReductionDecl>(D);
18128
18129 // Enter new function scope.
18130 PushFunctionScope();
18131 setFunctionHasBranchProtectedScope();
18132 getCurFunction()->setHasOMPDeclareReductionCombiner();
18133
18134 if (S != nullptr)
18135 PushDeclContext(S, DRD);
18136 else
18137 CurContext = DRD;
18138
18139 PushExpressionEvaluationContext(
18140 ExpressionEvaluationContext::PotentiallyEvaluated);
18141
18142 QualType ReductionType = DRD->getType();
18143 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
18144 // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
18145 // uses semantics of argument handles by value, but it should be passed by
18146 // reference. C lang does not support references, so pass all parameters as
18147 // pointers.
18148 // Create 'T omp_in;' variable.
18149 VarDecl *OmpInParm =
18150 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
18151 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
18152 // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
18153 // uses semantics of argument handles by value, but it should be passed by
18154 // reference. C lang does not support references, so pass all parameters as
18155 // pointers.
18156 // Create 'T omp_out;' variable.
18157 VarDecl *OmpOutParm =
18158 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
18159 if (S != nullptr) {
18160 PushOnScopeChains(OmpInParm, S);
18161 PushOnScopeChains(OmpOutParm, S);
18162 } else {
18163 DRD->addDecl(OmpInParm);
18164 DRD->addDecl(OmpOutParm);
18165 }
18166 Expr *InE =
18167 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
18168 Expr *OutE =
18169 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
18170 DRD->setCombinerData(InE, OutE);
18171}
18172
18173void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
18174 auto *DRD = cast<OMPDeclareReductionDecl>(D);
18175 DiscardCleanupsInEvaluationContext();
18176 PopExpressionEvaluationContext();
18177
18178 PopDeclContext();
18179 PopFunctionScopeInfo();
18180
18181 if (Combiner != nullptr)
18182 DRD->setCombiner(Combiner);
18183 else
18184 DRD->setInvalidDecl();
18185}
18186
18187VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
18188 auto *DRD = cast<OMPDeclareReductionDecl>(D);
18189
18190 // Enter new function scope.
18191 PushFunctionScope();
18192 setFunctionHasBranchProtectedScope();
18193
18194 if (S != nullptr)
18195 PushDeclContext(S, DRD);
18196 else
18197 CurContext = DRD;
18198
18199 PushExpressionEvaluationContext(
18200 ExpressionEvaluationContext::PotentiallyEvaluated);
18201
18202 QualType ReductionType = DRD->getType();
18203 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
18204 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
18205 // uses semantics of argument handles by value, but it should be passed by
18206 // reference. C lang does not support references, so pass all parameters as
18207 // pointers.
18208 // Create 'T omp_priv;' variable.
18209 VarDecl *OmpPrivParm =
18210 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
18211 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
18212 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
18213 // uses semantics of argument handles by value, but it should be passed by
18214 // reference. C lang does not support references, so pass all parameters as
18215 // pointers.
18216 // Create 'T omp_orig;' variable.
18217 VarDecl *OmpOrigParm =
18218 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
18219 if (S != nullptr) {
18220 PushOnScopeChains(OmpPrivParm, S);
18221 PushOnScopeChains(OmpOrigParm, S);
18222 } else {
18223 DRD->addDecl(OmpPrivParm);
18224 DRD->addDecl(OmpOrigParm);
18225 }
18226 Expr *OrigE =
18227 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
18228 Expr *PrivE =
18229 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
18230 DRD->setInitializerData(OrigE, PrivE);
18231 return OmpPrivParm;
18232}
18233
18234void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
18235 VarDecl *OmpPrivParm) {
18236 auto *DRD = cast<OMPDeclareReductionDecl>(D);
18237 DiscardCleanupsInEvaluationContext();
18238 PopExpressionEvaluationContext();
18239
18240 PopDeclContext();
18241 PopFunctionScopeInfo();
18242
18243 if (Initializer != nullptr) {
18244 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
18245 } else if (OmpPrivParm->hasInit()) {
18246 DRD->setInitializer(OmpPrivParm->getInit(),
18247 OmpPrivParm->isDirectInit()
18248 ? OMPDeclareReductionDecl::DirectInit
18249 : OMPDeclareReductionDecl::CopyInit);
18250 } else {
18251 DRD->setInvalidDecl();
18252 }
18253}
18254
18255Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
18256 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
18257 for (Decl *D : DeclReductions.get()) {
18258 if (IsValid) {
18259 if (S)
18260 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
18261 /*AddToContext=*/false);
18262 } else {
18263 D->setInvalidDecl();
18264 }
18265 }
18266 return DeclReductions;
18267}
18268
18269TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
18270 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
18271 QualType T = TInfo->getType();
18272 if (D.isInvalidType())
18273 return true;
18274
18275 if (getLangOpts().CPlusPlus) {
18276 // Check that there are no default arguments (C++ only).
18277 CheckExtraCXXDefaultArguments(D);
18278 }
18279
18280 return CreateParsedType(T, TInfo);
18281}
18282
18283QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
18284 TypeResult ParsedType) {
18285 assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
18286
18287 QualType MapperType = GetTypeFromParser(ParsedType.get());
18288 assert(!MapperType.isNull() && "Expect valid mapper type");
18289
18290 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
18291 // The type must be of struct, union or class type in C and C++
18292 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
18293 Diag(TyLoc, diag::err_omp_mapper_wrong_type);
18294 return QualType();
18295 }
18296 return MapperType;
18297}
18298
18299Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective(
18300 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
18301 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
18302 Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
18303 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
18304 forRedeclarationInCurContext());
18305 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
18306 // A mapper-identifier may not be redeclared in the current scope for the
18307 // same type or for a type that is compatible according to the base language
18308 // rules.
18309 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
18310 OMPDeclareMapperDecl *PrevDMD = nullptr;
18311 bool InCompoundScope = true;
18312 if (S != nullptr) {
18313 // Find previous declaration with the same name not referenced in other
18314 // declarations.
18315 FunctionScopeInfo *ParentFn = getEnclosingFunction();
18316 InCompoundScope =
18317 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
18318 LookupName(Lookup, S);
18319 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
18320 /*AllowInlineNamespace=*/false);
18321 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
18322 LookupResult::Filter Filter = Lookup.makeFilter();
18323 while (Filter.hasNext()) {
18324 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
18325 if (InCompoundScope) {
18326 auto I = UsedAsPrevious.find(PrevDecl);
18327 if (I == UsedAsPrevious.end())
18328 UsedAsPrevious[PrevDecl] = false;
18329 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
18330 UsedAsPrevious[D] = true;
18331 }
18332 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
18333 PrevDecl->getLocation();
18334 }
18335 Filter.done();
18336 if (InCompoundScope) {
18337 for (const auto &PrevData : UsedAsPrevious) {
18338 if (!PrevData.second) {
18339 PrevDMD = PrevData.first;
18340 break;
18341 }
18342 }
18343 }
18344 } else if (PrevDeclInScope) {
18345 auto *PrevDMDInScope = PrevDMD =
18346 cast<OMPDeclareMapperDecl>(PrevDeclInScope);
18347 do {
18348 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
18349 PrevDMDInScope->getLocation();
18350 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
18351 } while (PrevDMDInScope != nullptr);
18352 }
18353 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
18354 bool Invalid = false;
18355 if (I != PreviousRedeclTypes.end()) {
18356 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
18357 << MapperType << Name;
18358 Diag(I->second, diag::note_previous_definition);
18359 Invalid = true;
18360 }
18361 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name,
18362 MapperType, VN, Clauses, PrevDMD);
18363 if (S)
18364 PushOnScopeChains(DMD, S);
18365 else
18366 DC->addDecl(DMD);
18367 DMD->setAccess(AS);
18368 if (Invalid)
18369 DMD->setInvalidDecl();
18370
18371 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
18372 VD->setDeclContext(DMD);
18373 VD->setLexicalDeclContext(DMD);
18374 DMD->addDecl(VD);
18375 DMD->setMapperVarRef(MapperVarRef);
18376
18377 return DeclGroupPtrTy::make(DeclGroupRef(DMD));
18378}
18379
18380ExprResult
18381Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType,
18382 SourceLocation StartLoc,
18383 DeclarationName VN) {
18384 TypeSourceInfo *TInfo =
18385 Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
18386 auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(),
18387 StartLoc, StartLoc, VN.getAsIdentifierInfo(),
18388 MapperType, TInfo, SC_None);
18389 if (S)
18390 PushOnScopeChains(VD, S, /*AddToContext=*/false);
18391 Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
18392 DSAStack->addDeclareMapperVarRef(E);
18393 return E;
18394}
18395
18396bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
18397 assert(LangOpts.OpenMP && "Expected OpenMP mode.");
18398 const Expr *Ref = DSAStack->getDeclareMapperVarRef();
18399 if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref))
18400 return VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl();
18401 return true;
18402}
18403
18404const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const {
18405 assert(LangOpts.OpenMP && "Expected OpenMP mode.");
18406 return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl();
18407}
18408
18409OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
18410 SourceLocation StartLoc,
18411 SourceLocation LParenLoc,
18412 SourceLocation EndLoc) {
18413 Expr *ValExpr = NumTeams;
18414 Stmt *HelperValStmt = nullptr;
18415
18416 // OpenMP [teams Constrcut, Restrictions]
18417 // The num_teams expression must evaluate to a positive integer value.
18418 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
18419 /*StrictlyPositive=*/true))
18420 return nullptr;
18421
18422 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
18423 OpenMPDirectiveKind CaptureRegion =
18424 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
18425 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18426 ValExpr = MakeFullExpr(ValExpr).get();
18427 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18428 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18429 HelperValStmt = buildPreInits(Context, Captures);
18430 }
18431
18432 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
18433 StartLoc, LParenLoc, EndLoc);
18434}
18435
18436OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
18437 SourceLocation StartLoc,
18438 SourceLocation LParenLoc,
18439 SourceLocation EndLoc) {
18440 Expr *ValExpr = ThreadLimit;
18441 Stmt *HelperValStmt = nullptr;
18442
18443 // OpenMP [teams Constrcut, Restrictions]
18444 // The thread_limit expression must evaluate to a positive integer value.
18445 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
18446 /*StrictlyPositive=*/true))
18447 return nullptr;
18448
18449 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
18450 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
18451 DKind, OMPC_thread_limit, LangOpts.OpenMP);
18452 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18453 ValExpr = MakeFullExpr(ValExpr).get();
18454 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18455 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18456 HelperValStmt = buildPreInits(Context, Captures);
18457 }
18458
18459 return new (Context) OMPThreadLimitClause(
18460 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
18461}
18462
18463OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
18464 SourceLocation StartLoc,
18465 SourceLocation LParenLoc,
18466 SourceLocation EndLoc) {
18467 Expr *ValExpr = Priority;
18468 Stmt *HelperValStmt = nullptr;
18469 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18470
18471 // OpenMP [2.9.1, task Constrcut]
18472 // The priority-value is a non-negative numerical scalar expression.
18473 if (!isNonNegativeIntegerValue(
18474 ValExpr, *this, OMPC_priority,
18475 /*StrictlyPositive=*/false, /*BuildCapture=*/true,
18476 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18477 return nullptr;
18478
18479 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
18480 StartLoc, LParenLoc, EndLoc);
18481}
18482
18483OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
18484 SourceLocation StartLoc,
18485 SourceLocation LParenLoc,
18486 SourceLocation EndLoc) {
18487 Expr *ValExpr = Grainsize;
18488 Stmt *HelperValStmt = nullptr;
18489 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18490
18491 // OpenMP [2.9.2, taskloop Constrcut]
18492 // The parameter of the grainsize clause must be a positive integer
18493 // expression.
18494 if (!isNonNegativeIntegerValue(
18495 ValExpr, *this, OMPC_grainsize,
18496 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
18497 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18498 return nullptr;
18499
18500 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
18501 StartLoc, LParenLoc, EndLoc);
18502}
18503
18504OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
18505 SourceLocation StartLoc,
18506 SourceLocation LParenLoc,
18507 SourceLocation EndLoc) {
18508 Expr *ValExpr = NumTasks;
18509 Stmt *HelperValStmt = nullptr;
18510 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18511
18512 // OpenMP [2.9.2, taskloop Constrcut]
18513 // The parameter of the num_tasks clause must be a positive integer
18514 // expression.
18515 if (!isNonNegativeIntegerValue(
18516 ValExpr, *this, OMPC_num_tasks,
18517 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
18518 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18519 return nullptr;
18520
18521 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
18522 StartLoc, LParenLoc, EndLoc);
18523}
18524
18525OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
18526 SourceLocation LParenLoc,
18527 SourceLocation EndLoc) {
18528 // OpenMP [2.13.2, critical construct, Description]
18529 // ... where hint-expression is an integer constant expression that evaluates
18530 // to a valid lock hint.
18531 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
18532 if (HintExpr.isInvalid())
18533 return nullptr;
18534 return new (Context)
18535 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
18536}
18537
18538/// Tries to find omp_event_handle_t type.
18539static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
18540 DSAStackTy *Stack) {
18541 QualType OMPEventHandleT = Stack->getOMPEventHandleT();
18542 if (!OMPEventHandleT.isNull())
18543 return true;
18544 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
18545 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
18546 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
18547 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
18548 return false;
18549 }
18550 Stack->setOMPEventHandleT(PT.get());
18551 return true;
18552}
18553
18554OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
18555 SourceLocation LParenLoc,
18556 SourceLocation EndLoc) {
18557 if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
18558 !Evt->isInstantiationDependent() &&
18559 !Evt->containsUnexpandedParameterPack()) {
18560 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack))
18561 return nullptr;
18562 // OpenMP 5.0, 2.10.1 task Construct.
18563 // event-handle is a variable of the omp_event_handle_t type.
18564 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
18565 if (!Ref) {
18566 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18567 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
18568 return nullptr;
18569 }
18570 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
18571 if (!VD) {
18572 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18573 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
18574 return nullptr;
18575 }
18576 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(),
18577 VD->getType()) ||
18578 VD->getType().isConstant(Context)) {
18579 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18580 << "omp_event_handle_t" << 1 << VD->getType()
18581 << Evt->getSourceRange();
18582 return nullptr;
18583 }
18584 // OpenMP 5.0, 2.10.1 task Construct
18585 // [detach clause]... The event-handle will be considered as if it was
18586 // specified on a firstprivate clause.
18587 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false);
18588 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
18589 DVar.RefExpr) {
18590 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
18591 << getOpenMPClauseName(DVar.CKind)
18592 << getOpenMPClauseName(OMPC_firstprivate);
18593 reportOriginalDsa(*this, DSAStack, VD, DVar);
18594 return nullptr;
18595 }
18596 }
18597
18598 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
18599}
18600
18601OMPClause *Sema::ActOnOpenMPDistScheduleClause(
18602 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
18603 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
18604 SourceLocation EndLoc) {
18605 if (Kind == OMPC_DIST_SCHEDULE_unknown) {
18606 std::string Values;
18607 Values += "'";
18608 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
18609 Values += "'";
18610 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18611 << Values << getOpenMPClauseName(OMPC_dist_schedule);
18612 return nullptr;
18613 }
18614 Expr *ValExpr = ChunkSize;
18615 Stmt *HelperValStmt = nullptr;
18616 if (ChunkSize) {
18617 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
18618 !ChunkSize->isInstantiationDependent() &&
18619 !ChunkSize->containsUnexpandedParameterPack()) {
18620 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
18621 ExprResult Val =
18622 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
18623 if (Val.isInvalid())
18624 return nullptr;
18625
18626 ValExpr = Val.get();
18627
18628 // OpenMP [2.7.1, Restrictions]
18629 // chunk_size must be a loop invariant integer expression with a positive
18630 // value.
18631 if (Optional<llvm::APSInt> Result =
18632 ValExpr->getIntegerConstantExpr(Context)) {
18633 if (Result->isSigned() && !Result->isStrictlyPositive()) {
18634 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
18635 << "dist_schedule" << ChunkSize->getSourceRange();
18636 return nullptr;
18637 }
18638 } else if (getOpenMPCaptureRegionForClause(
18639 DSAStack->getCurrentDirective(), OMPC_dist_schedule,
18640 LangOpts.OpenMP) != OMPD_unknown &&
18641 !CurContext->isDependentContext()) {
18642 ValExpr = MakeFullExpr(ValExpr).get();
18643 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18644 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18645 HelperValStmt = buildPreInits(Context, Captures);
18646 }
18647 }
18648 }
18649
18650 return new (Context)
18651 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
18652 Kind, ValExpr, HelperValStmt);
18653}
18654
18655OMPClause *Sema::ActOnOpenMPDefaultmapClause(
18656 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
18657 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
18658 SourceLocation KindLoc, SourceLocation EndLoc) {
18659 if (getLangOpts().OpenMP < 50) {
18660 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
18661 Kind != OMPC_DEFAULTMAP_scalar) {
18662 std::string Value;
18663 SourceLocation Loc;
18664 Value += "'";
18665 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
18666 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
18667 OMPC_DEFAULTMAP_MODIFIER_tofrom);
18668 Loc = MLoc;
18669 } else {
18670 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
18671 OMPC_DEFAULTMAP_scalar);
18672 Loc = KindLoc;
18673 }
18674 Value += "'";
18675 Diag(Loc, diag::err_omp_unexpected_clause_value)
18676 << Value << getOpenMPClauseName(OMPC_defaultmap);
18677 return nullptr;
18678 }
18679 } else {
18680 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
18681 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
18682 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
18683 if (!isDefaultmapKind || !isDefaultmapModifier) {
18684 StringRef KindValue = "'scalar', 'aggregate', 'pointer'";
18685 if (LangOpts.OpenMP == 50) {
18686 StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
18687 "'firstprivate', 'none', 'default'";
18688 if (!isDefaultmapKind && isDefaultmapModifier) {
18689 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18690 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
18691 } else if (isDefaultmapKind && !isDefaultmapModifier) {
18692 Diag(MLoc, diag::err_omp_unexpected_clause_value)
18693 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
18694 } else {
18695 Diag(MLoc, diag::err_omp_unexpected_clause_value)
18696 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
18697 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18698 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
18699 }
18700 } else {
18701 StringRef ModifierValue =
18702 "'alloc', 'from', 'to', 'tofrom', "
18703 "'firstprivate', 'none', 'default', 'present'";
18704 if (!isDefaultmapKind && isDefaultmapModifier) {
18705 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18706 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
18707 } else if (isDefaultmapKind && !isDefaultmapModifier) {
18708 Diag(MLoc, diag::err_omp_unexpected_clause_value)
18709 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
18710 } else {
18711 Diag(MLoc, diag::err_omp_unexpected_clause_value)
18712 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
18713 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18714 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
18715 }
18716 }
18717 return nullptr;
18718 }
18719
18720 // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
18721 // At most one defaultmap clause for each category can appear on the
18722 // directive.
18723 if (DSAStack->checkDefaultmapCategory(Kind)) {
18724 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
18725 return nullptr;
18726 }
18727 }
18728 if (Kind == OMPC_DEFAULTMAP_unknown) {
18729 // Variable category is not specified - mark all categories.
18730 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
18731 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
18732 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
18733 } else {
18734 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
18735 }
18736
18737 return new (Context)
18738 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
18739}
18740
18741bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) {
18742 DeclContext *CurLexicalContext = getCurLexicalContext();
18743 if (!CurLexicalContext->isFileContext() &&
18744 !CurLexicalContext->isExternCContext() &&
18745 !CurLexicalContext->isExternCXXContext() &&
18746 !isa<CXXRecordDecl>(CurLexicalContext) &&
18747 !isa<ClassTemplateDecl>(CurLexicalContext) &&
18748 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
18749 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
18750 Diag(Loc, diag::err_omp_region_not_file_context);
18751 return false;
18752 }
18753 DeclareTargetNesting.push_back(Loc);
18754 return true;
18755}
18756
18757void Sema::ActOnFinishOpenMPDeclareTargetDirective() {
18758 assert(!DeclareTargetNesting.empty() &&
18759 "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
18760 DeclareTargetNesting.pop_back();
18761}
18762
18763NamedDecl *
18764Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec,
18765 const DeclarationNameInfo &Id,
18766 NamedDeclSetType &SameDirectiveDecls) {
18767 LookupResult Lookup(*this, Id, LookupOrdinaryName);
18768 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
18769
18770 if (Lookup.isAmbiguous())
18771 return nullptr;
18772 Lookup.suppressDiagnostics();
18773
18774 if (!Lookup.isSingleResult()) {
18775 VarOrFuncDeclFilterCCC CCC(*this);
18776 if (TypoCorrection Corrected =
18777 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
18778 CTK_ErrorRecovery)) {
18779 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
18780 << Id.getName());
18781 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
18782 return nullptr;
18783 }
18784
18785 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
18786 return nullptr;
18787 }
18788
18789 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
18790 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
18791 !isa<FunctionTemplateDecl>(ND)) {
18792 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
18793 return nullptr;
18794 }
18795 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
18796 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
18797 return ND;
18798}
18799
18800void Sema::ActOnOpenMPDeclareTargetName(
18801 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT,
18802 OMPDeclareTargetDeclAttr::DevTypeTy DT) {
18803 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
18804 isa<FunctionTemplateDecl>(ND)) &&
18805 "Expected variable, function or function template.");
18806
18807 // Diagnose marking after use as it may lead to incorrect diagnosis and
18808 // codegen.
18809 if (LangOpts.OpenMP >= 50 &&
18810 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
18811 Diag(Loc, diag::warn_omp_declare_target_after_first_use);
18812
18813 auto *VD = cast<ValueDecl>(ND);
18814 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
18815 OMPDeclareTargetDeclAttr::getDeviceType(VD);
18816 Optional<SourceLocation> AttrLoc = OMPDeclareTargetDeclAttr::getLocation(VD);
18817 if (DevTy.hasValue() && *DevTy != DT &&
18818 (DeclareTargetNesting.empty() ||
18819 *AttrLoc != DeclareTargetNesting.back())) {
18820 Diag(Loc, diag::err_omp_device_type_mismatch)
18821 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT)
18822 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy);
18823 return;
18824 }
18825 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
18826 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
18827 if (!Res || (!DeclareTargetNesting.empty() &&
18828 *AttrLoc == DeclareTargetNesting.back())) {
18829 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
18830 Context, MT, DT, DeclareTargetNesting.size() + 1,
18831 SourceRange(Loc, Loc));
18832 ND->addAttr(A);
18833 if (ASTMutationListener *ML = Context.getASTMutationListener())
18834 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
18835 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
18836 } else if (*Res != MT) {
18837 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
18838 }
18839}
18840
18841static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
18842 Sema &SemaRef, Decl *D) {
18843 if (!D || !isa<VarDecl>(D))
18844 return;
18845 auto *VD = cast<VarDecl>(D);
18846 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
18847 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
18848 if (SemaRef.LangOpts.OpenMP >= 50 &&
18849 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
18850 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
18851 VD->hasGlobalStorage()) {
18852 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
18853 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
18854 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
18855 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
18856 // If a lambda declaration and definition appears between a
18857 // declare target directive and the matching end declare target
18858 // directive, all variables that are captured by the lambda
18859 // expression must also appear in a to clause.
18860 SemaRef.Diag(VD->getLocation(),
18861 diag::err_omp_lambda_capture_in_declare_target_not_to);
18862 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
18863 << VD << 0 << SR;
18864 return;
18865 }
18866 }
18867 if (MapTy.hasValue())
18868 return;
18869 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
18870 SemaRef.Diag(SL, diag::note_used_here) << SR;
18871}
18872
18873static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
18874 Sema &SemaRef, DSAStackTy *Stack,
18875 ValueDecl *VD) {
18876 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
18877 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
18878 /*FullCheck=*/false);
18879}
18880
18881void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
18882 SourceLocation IdLoc) {
18883 if (!D || D->isInvalidDecl())
18884 return;
18885 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
18886 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
18887 if (auto *VD = dyn_cast<VarDecl>(D)) {
18888 // Only global variables can be marked as declare target.
18889 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
18890 !VD->isStaticDataMember())
18891 return;
18892 // 2.10.6: threadprivate variable cannot appear in a declare target
18893 // directive.
18894 if (DSAStack->isThreadPrivate(VD)) {
18895 Diag(SL, diag::err_omp_threadprivate_in_target);
18896 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
18897 return;
18898 }
18899 }
18900 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
18901 D = FTD->getTemplatedDecl();
18902 if (auto *FD = dyn_cast<FunctionDecl>(D)) {
18903 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
18904 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
18905 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
18906 Diag(IdLoc, diag::err_omp_function_in_link_clause);
18907 Diag(FD->getLocation(), diag::note_defined_here) << FD;
18908 return;
18909 }
18910 }
18911 if (auto *VD = dyn_cast<ValueDecl>(D)) {
18912 // Problem if any with var declared with incomplete type will be reported
18913 // as normal, so no need to check it here.
18914 if ((E || !VD->getType()->isIncompleteType()) &&
18915 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD))
18916 return;
18917 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
18918 // Checking declaration inside declare target region.
18919 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
18920 isa<FunctionTemplateDecl>(D)) {
18921 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
18922 Context, OMPDeclareTargetDeclAttr::MT_To,
18923 OMPDeclareTargetDeclAttr::DT_Any, DeclareTargetNesting.size(),
18924 SourceRange(DeclareTargetNesting.back(),
18925 DeclareTargetNesting.back()));
18926 D->addAttr(A);
18927 if (ASTMutationListener *ML = Context.getASTMutationListener())
18928 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
18929 }
18930 return;
18931 }
18932 }
18933 if (!E)
18934 return;
18935 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
18936}
18937
18938OMPClause *Sema::ActOnOpenMPToClause(
18939 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
18940 ArrayRef<SourceLocation> MotionModifiersLoc,
18941 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
18942 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
18943 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
18944 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
18945 OMPC_MOTION_MODIFIER_unknown};
18946 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
18947
18948 // Process motion-modifiers, flag errors for duplicate modifiers.
18949 unsigned Count = 0;
18950 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
18951 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
18952 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
18953 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
18954 continue;
18955 }
18956 assert(Count < NumberOfOMPMotionModifiers &&
18957 "Modifiers exceed the allowed number of motion modifiers");
18958 Modifiers[Count] = MotionModifiers[I];
18959 ModifiersLoc[Count] = MotionModifiersLoc[I];
18960 ++Count;
18961 }
18962
18963 MappableVarListInfo MVLI(VarList);
18964 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
18965 MapperIdScopeSpec, MapperId, UnresolvedMappers);
18966 if (MVLI.ProcessedVarList.empty())
18967 return nullptr;
18968
18969 return OMPToClause::Create(
18970 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
18971 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
18972 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
18973}
18974
18975OMPClause *Sema::ActOnOpenMPFromClause(
18976 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
18977 ArrayRef<SourceLocation> MotionModifiersLoc,
18978 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
18979 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
18980 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
18981 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
18982 OMPC_MOTION_MODIFIER_unknown};
18983 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
18984
18985 // Process motion-modifiers, flag errors for duplicate modifiers.
18986 unsigned Count = 0;
18987 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
18988 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
18989 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
18990 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
18991 continue;
18992 }
18993 assert(Count < NumberOfOMPMotionModifiers &&
18994 "Modifiers exceed the allowed number of motion modifiers");
18995 Modifiers[Count] = MotionModifiers[I];
18996 ModifiersLoc[Count] = MotionModifiersLoc[I];
18997 ++Count;
18998 }
18999
19000 MappableVarListInfo MVLI(VarList);
19001 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
19002 MapperIdScopeSpec, MapperId, UnresolvedMappers);
19003 if (MVLI.ProcessedVarList.empty())
19004 return nullptr;
19005
19006 return OMPFromClause::Create(
19007 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
19008 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
19009 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
19010}
19011
19012OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
19013 const OMPVarListLocTy &Locs) {
19014 MappableVarListInfo MVLI(VarList);
19015 SmallVector<Expr *, 8> PrivateCopies;
19016 SmallVector<Expr *, 8> Inits;
19017
19018 for (Expr *RefExpr : VarList) {
19019 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
19020 SourceLocation ELoc;
19021 SourceRange ERange;
19022 Expr *SimpleRefExpr = RefExpr;
19023 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19024 if (Res.second) {
19025 // It will be analyzed later.
19026 MVLI.ProcessedVarList.push_back(RefExpr);
19027 PrivateCopies.push_back(nullptr);
19028 Inits.push_back(nullptr);
19029 }
19030 ValueDecl *D = Res.first;
19031 if (!D)
19032 continue;
19033
19034 QualType Type = D->getType();
19035 Type = Type.getNonReferenceType().getUnqualifiedType();
19036
19037 auto *VD = dyn_cast<VarDecl>(D);
19038
19039 // Item should be a pointer or reference to pointer.
19040 if (!Type->isPointerType()) {
19041 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
19042 << 0 << RefExpr->getSourceRange();
19043 continue;
19044 }
19045
19046 // Build the private variable and the expression that refers to it.
19047 auto VDPrivate =
19048 buildVarDecl(*this, ELoc, Type, D->getName(),
19049 D->hasAttrs() ? &D->getAttrs() : nullptr,
19050 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
19051 if (VDPrivate->isInvalidDecl())
19052 continue;
19053
19054 CurContext->addDecl(VDPrivate);
19055 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
19056 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
19057
19058 // Add temporary variable to initialize the private copy of the pointer.
19059 VarDecl *VDInit =
19060 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
19061 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
19062 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
19063 AddInitializerToDecl(VDPrivate,
19064 DefaultLvalueConversion(VDInitRefExpr).get(),
19065 /*DirectInit=*/false);
19066
19067 // If required, build a capture to implement the privatization initialized
19068 // with the current list item value.
19069 DeclRefExpr *Ref = nullptr;
19070 if (!VD)
19071 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
19072 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
19073 PrivateCopies.push_back(VDPrivateRefExpr);
19074 Inits.push_back(VDInitRefExpr);
19075
19076 // We need to add a data sharing attribute for this variable to make sure it
19077 // is correctly captured. A variable that shows up in a use_device_ptr has
19078 // similar properties of a first private variable.
19079 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
19080
19081 // Create a mappable component for the list item. List items in this clause
19082 // only need a component.
19083 MVLI.VarBaseDeclarations.push_back(D);
19084 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
19085 MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
19086 /*IsNonContiguous=*/false);
19087 }
19088
19089 if (MVLI.ProcessedVarList.empty())
19090 return nullptr;
19091
19092 return OMPUseDevicePtrClause::Create(
19093 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
19094 MVLI.VarBaseDeclarations, MVLI.VarComponents);
19095}
19096
19097OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
19098 const OMPVarListLocTy &Locs) {
19099 MappableVarListInfo MVLI(VarList);
19100
19101 for (Expr *RefExpr : VarList) {
19102 assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.");
19103 SourceLocation ELoc;
19104 SourceRange ERange;
19105 Expr *SimpleRefExpr = RefExpr;
19106 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
19107 /*AllowArraySection=*/true);
19108 if (Res.second) {
19109 // It will be analyzed later.
19110 MVLI.ProcessedVarList.push_back(RefExpr);
19111 }
19112 ValueDecl *D = Res.first;
19113 if (!D)
19114 continue;
19115 auto *VD = dyn_cast<VarDecl>(D);
19116
19117 // If required, build a capture to implement the privatization initialized
19118 // with the current list item value.
19119 DeclRefExpr *Ref = nullptr;
19120 if (!VD)
19121 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
19122 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
19123
19124 // We need to add a data sharing attribute for this variable to make sure it
19125 // is correctly captured. A variable that shows up in a use_device_addr has
19126 // similar properties of a first private variable.
19127 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
19128
19129 // Create a mappable component for the list item. List items in this clause
19130 // only need a component.
19131 MVLI.VarBaseDeclarations.push_back(D);
19132 MVLI.VarComponents.emplace_back();
19133 Expr *Component = SimpleRefExpr;
19134 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
19135 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
19136 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
19137 MVLI.VarComponents.back().emplace_back(Component, D,
19138 /*IsNonContiguous=*/false);
19139 }
19140
19141 if (MVLI.ProcessedVarList.empty())
19142 return nullptr;
19143
19144 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
19145 MVLI.VarBaseDeclarations,
19146 MVLI.VarComponents);
19147}
19148
19149OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
19150 const OMPVarListLocTy &Locs) {
19151 MappableVarListInfo MVLI(VarList);
19152 for (Expr *RefExpr : VarList) {
19153 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
19154 SourceLocation ELoc;
19155 SourceRange ERange;
19156 Expr *SimpleRefExpr = RefExpr;
19157 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19158 if (Res.second) {
19159 // It will be analyzed later.
19160 MVLI.ProcessedVarList.push_back(RefExpr);
19161 }
19162 ValueDecl *D = Res.first;
19163 if (!D)
19164 continue;
19165
19166 QualType Type = D->getType();
19167 // item should be a pointer or array or reference to pointer or array
19168 if (!Type.getNonReferenceType()->isPointerType() &&
19169 !Type.getNonReferenceType()->isArrayType()) {
19170 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
19171 << 0 << RefExpr->getSourceRange();
19172 continue;
19173 }
19174
19175 // Check if the declaration in the clause does not show up in any data
19176 // sharing attribute.
19177 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
19178 if (isOpenMPPrivate(DVar.CKind)) {
19179 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
19180 << getOpenMPClauseName(DVar.CKind)
19181 << getOpenMPClauseName(OMPC_is_device_ptr)
19182 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
19183 reportOriginalDsa(*this, DSAStack, D, DVar);
19184 continue;
19185 }
19186
19187 const Expr *ConflictExpr;
19188 if (DSAStack->checkMappableExprComponentListsForDecl(
19189 D, /*CurrentRegionOnly=*/true,
19190 [&ConflictExpr](
19191 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
19192 OpenMPClauseKind) -> bool {
19193 ConflictExpr = R.front().getAssociatedExpression();
19194 return true;
19195 })) {
19196 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
19197 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
19198 << ConflictExpr->getSourceRange();
19199 continue;
19200 }
19201
19202 // Store the components in the stack so that they can be used to check
19203 // against other clauses later on.
19204 OMPClauseMappableExprCommon::MappableComponent MC(
19205 SimpleRefExpr, D, /*IsNonContiguous=*/false);
19206 DSAStack->addMappableExpressionComponents(
19207 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
19208
19209 // Record the expression we've just processed.
19210 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
19211
19212 // Create a mappable component for the list item. List items in this clause
19213 // only need a component. We use a null declaration to signal fields in
19214 // 'this'.
19215 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
19216 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
19217 "Unexpected device pointer expression!");
19218 MVLI.VarBaseDeclarations.push_back(
19219 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
19220 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
19221 MVLI.VarComponents.back().push_back(MC);
19222 }
19223
19224 if (MVLI.ProcessedVarList.empty())
19225 return nullptr;
19226
19227 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
19228 MVLI.VarBaseDeclarations,
19229 MVLI.VarComponents);
19230}
19231
19232OMPClause *Sema::ActOnOpenMPAllocateClause(
19233 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
19234 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
19235 if (Allocator) {
19236 // OpenMP [2.11.4 allocate Clause, Description]
19237 // allocator is an expression of omp_allocator_handle_t type.
19238 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack))
19239 return nullptr;
19240
19241 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
19242 if (AllocatorRes.isInvalid())
19243 return nullptr;
19244 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
19245 DSAStack->getOMPAllocatorHandleT(),
19246 Sema::AA_Initializing,
19247 /*AllowExplicit=*/true);
19248 if (AllocatorRes.isInvalid())
19249 return nullptr;
19250 Allocator = AllocatorRes.get();
19251 } else {
19252 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
19253 // allocate clauses that appear on a target construct or on constructs in a
19254 // target region must specify an allocator expression unless a requires
19255 // directive with the dynamic_allocators clause is present in the same
19256 // compilation unit.
19257 if (LangOpts.OpenMPIsDevice &&
19258 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
19259 targetDiag(StartLoc, diag::err_expected_allocator_expression);
19260 }
19261 // Analyze and build list of variables.
19262 SmallVector<Expr *, 8> Vars;
19263 for (Expr *RefExpr : VarList) {
19264 assert(RefExpr && "NULL expr in OpenMP private clause.");
19265 SourceLocation ELoc;
19266 SourceRange ERange;
19267 Expr *SimpleRefExpr = RefExpr;
19268 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19269 if (Res.second) {
19270 // It will be analyzed later.
19271 Vars.push_back(RefExpr);
19272 }
19273 ValueDecl *D = Res.first;
19274 if (!D)
19275 continue;
19276
19277 auto *VD = dyn_cast<VarDecl>(D);
19278 DeclRefExpr *Ref = nullptr;
19279 if (!VD && !CurContext->isDependentContext())
19280 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
19281 Vars.push_back((VD || CurContext->isDependentContext())
19282 ? RefExpr->IgnoreParens()
19283 : Ref);
19284 }
19285
19286 if (Vars.empty())
19287 return nullptr;
19288
19289 if (Allocator)
19290 DSAStack->addInnerAllocatorExpr(Allocator);
19291 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
19292 ColonLoc, EndLoc, Vars);
19293}
19294
19295OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
19296 SourceLocation StartLoc,
19297 SourceLocation LParenLoc,
19298 SourceLocation EndLoc) {
19299 SmallVector<Expr *, 8> Vars;
19300 for (Expr *RefExpr : VarList) {
19301 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
19302 SourceLocation ELoc;
19303 SourceRange ERange;
19304 Expr *SimpleRefExpr = RefExpr;
19305 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19306 if (Res.second)
19307 // It will be analyzed later.
19308 Vars.push_back(RefExpr);
19309 ValueDecl *D = Res.first;
19310 if (!D)
19311 continue;
19312
19313 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
19314 // A list-item cannot appear in more than one nontemporal clause.
19315 if (const Expr *PrevRef =
19316 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
19317 Diag(ELoc, diag::err_omp_used_in_clause_twice)
19318 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
19319 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
19320 << getOpenMPClauseName(OMPC_nontemporal);
19321 continue;
19322 }
19323
19324 Vars.push_back(RefExpr);
19325 }
19326
19327 if (Vars.empty())
19328 return nullptr;
19329
19330 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
19331 Vars);
19332}
19333
19334OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
19335 SourceLocation StartLoc,
19336 SourceLocation LParenLoc,
19337 SourceLocation EndLoc) {
19338 SmallVector<Expr *, 8> Vars;
19339 for (Expr *RefExpr : VarList) {
19340 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
19341 SourceLocation ELoc;
19342 SourceRange ERange;
19343 Expr *SimpleRefExpr = RefExpr;
19344 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
19345 /*AllowArraySection=*/true);
19346 if (Res.second)
19347 // It will be analyzed later.
19348 Vars.push_back(RefExpr);
19349 ValueDecl *D = Res.first;
19350 if (!D)
19351 continue;
19352
19353 const DSAStackTy::DSAVarData DVar =
19354 DSAStack->getTopDSA(D, /*FromParent=*/true);
19355 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
19356 // A list item that appears in the inclusive or exclusive clause must appear
19357 // in a reduction clause with the inscan modifier on the enclosing
19358 // worksharing-loop, worksharing-loop SIMD, or simd construct.
19359 if (DVar.CKind != OMPC_reduction ||
19360 DVar.Modifier != OMPC_REDUCTION_inscan)
19361 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
19362 << RefExpr->getSourceRange();
19363
19364 if (DSAStack->getParentDirective() != OMPD_unknown)
19365 DSAStack->markDeclAsUsedInScanDirective(D);
19366 Vars.push_back(RefExpr);
19367 }
19368
19369 if (Vars.empty())
19370 return nullptr;
19371
19372 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
19373}
19374
19375OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
19376 SourceLocation StartLoc,
19377 SourceLocation LParenLoc,
19378 SourceLocation EndLoc) {
19379 SmallVector<Expr *, 8> Vars;
19380 for (Expr *RefExpr : VarList) {
19381 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
19382 SourceLocation ELoc;
19383 SourceRange ERange;
19384 Expr *SimpleRefExpr = RefExpr;
19385 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
19386 /*AllowArraySection=*/true);
19387 if (Res.second)
19388 // It will be analyzed later.
19389 Vars.push_back(RefExpr);
19390 ValueDecl *D = Res.first;
19391 if (!D)
19392 continue;
19393
19394 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
19395 DSAStackTy::DSAVarData DVar;
19396 if (ParentDirective != OMPD_unknown)
19397 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true);
19398 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
19399 // A list item that appears in the inclusive or exclusive clause must appear
19400 // in a reduction clause with the inscan modifier on the enclosing
19401 // worksharing-loop, worksharing-loop SIMD, or simd construct.
19402 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
19403 DVar.Modifier != OMPC_REDUCTION_inscan) {
19404 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
19405 << RefExpr->getSourceRange();
19406 } else {
19407 DSAStack->markDeclAsUsedInScanDirective(D);
19408 }
19409 Vars.push_back(RefExpr);
19410 }
19411
19412 if (Vars.empty())
19413 return nullptr;
19414
19415 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
19416}
19417
19418/// Tries to find omp_alloctrait_t type.
19419static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
19420 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
19421 if (!OMPAlloctraitT.isNull())
19422 return true;
19423 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
19424 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
19425 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
19426 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
19427 return false;
19428 }
19429 Stack->setOMPAlloctraitT(PT.get());
19430 return true;
19431}
19432
19433OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
19434 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
19435 ArrayRef<UsesAllocatorsData> Data) {
19436 // OpenMP [2.12.5, target Construct]
19437 // allocator is an identifier of omp_allocator_handle_t type.
19438 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack))
19439 return nullptr;
19440 // OpenMP [2.12.5, target Construct]
19441 // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
19442 if (llvm::any_of(
19443 Data,
19444 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
19445 !findOMPAlloctraitT(*this, StartLoc, DSAStack))
19446 return nullptr;
19447 llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
19448 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
19449 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
19450 StringRef Allocator =
19451 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
19452 DeclarationName AllocatorName = &Context.Idents.get(Allocator);
19453 PredefinedAllocators.insert(LookupSingleName(
19454 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
19455 }
19456
19457 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
19458 for (const UsesAllocatorsData &D : Data) {
19459 Expr *AllocatorExpr = nullptr;
19460 // Check allocator expression.
19461 if (D.Allocator->isTypeDependent()) {
19462 AllocatorExpr = D.Allocator;
19463 } else {
19464 // Traits were specified - need to assign new allocator to the specified
19465 // allocator, so it must be an lvalue.
19466 AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
19467 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
19468 bool IsPredefinedAllocator = false;
19469 if (DRE)
19470 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl());
19471 if (!DRE ||
19472 !(Context.hasSameUnqualifiedType(
19473 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) ||
19474 Context.typesAreCompatible(AllocatorExpr->getType(),
19475 DSAStack->getOMPAllocatorHandleT(),
19476 /*CompareUnqualified=*/true)) ||
19477 (!IsPredefinedAllocator &&
19478 (AllocatorExpr->getType().isConstant(Context) ||
19479 !AllocatorExpr->isLValue()))) {
19480 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
19481 << "omp_allocator_handle_t" << (DRE ? 1 : 0)
19482 << AllocatorExpr->getType() << D.Allocator->getSourceRange();
19483 continue;
19484 }
19485 // OpenMP [2.12.5, target Construct]
19486 // Predefined allocators appearing in a uses_allocators clause cannot have
19487 // traits specified.
19488 if (IsPredefinedAllocator && D.AllocatorTraits) {
19489 Diag(D.AllocatorTraits->getExprLoc(),
19490 diag::err_omp_predefined_allocator_with_traits)
19491 << D.AllocatorTraits->getSourceRange();
19492 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
19493 << cast<NamedDecl>(DRE->getDecl())->getName()
19494 << D.Allocator->getSourceRange();
19495 continue;
19496 }
19497 // OpenMP [2.12.5, target Construct]
19498 // Non-predefined allocators appearing in a uses_allocators clause must
19499 // have traits specified.
19500 if (!IsPredefinedAllocator && !D.AllocatorTraits) {
19501 Diag(D.Allocator->getExprLoc(),
19502 diag::err_omp_nonpredefined_allocator_without_traits);
19503 continue;
19504 }
19505 // No allocator traits - just convert it to rvalue.
19506 if (!D.AllocatorTraits)
19507 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
19508 DSAStack->addUsesAllocatorsDecl(
19509 DRE->getDecl(),
19510 IsPredefinedAllocator
19511 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
19512 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
19513 }
19514 Expr *AllocatorTraitsExpr = nullptr;
19515 if (D.AllocatorTraits) {
19516 if (D.AllocatorTraits->isTypeDependent()) {
19517 AllocatorTraitsExpr = D.AllocatorTraits;
19518 } else {
19519 // OpenMP [2.12.5, target Construct]
19520 // Arrays that contain allocator traits that appear in a uses_allocators
19521 // clause must be constant arrays, have constant values and be defined
19522 // in the same scope as the construct in which the clause appears.
19523 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
19524 // Check that traits expr is a constant array.
19525 QualType TraitTy;
19526 if (const ArrayType *Ty =
19527 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
19528 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
19529 TraitTy = ConstArrayTy->getElementType();
19530 if (TraitTy.isNull() ||
19531 !(Context.hasSameUnqualifiedType(TraitTy,
19532 DSAStack->getOMPAlloctraitT()) ||
19533 Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(),
19534 /*CompareUnqualified=*/true))) {
19535 Diag(D.AllocatorTraits->getExprLoc(),
19536 diag::err_omp_expected_array_alloctraits)
19537 << AllocatorTraitsExpr->getType();
19538 continue;
19539 }
19540 // Do not map by default allocator traits if it is a standalone
19541 // variable.
19542 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
19543 DSAStack->addUsesAllocatorsDecl(
19544 DRE->getDecl(),
19545 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
19546 }
19547 }
19548 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
19549 NewD.Allocator = AllocatorExpr;
19550 NewD.AllocatorTraits = AllocatorTraitsExpr;
19551 NewD.LParenLoc = D.LParenLoc;
19552 NewD.RParenLoc = D.RParenLoc;
19553 }
19554 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
19555 NewData);
19556}
19557
19558OMPClause *Sema::ActOnOpenMPAffinityClause(
19559 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
19560 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
19561 SmallVector<Expr *, 8> Vars;
19562 for (Expr *RefExpr : Locators) {
19563 assert(RefExpr && "NULL expr in OpenMP shared clause.");
19564 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
19565 // It will be analyzed later.
19566 Vars.push_back(RefExpr);
19567 continue;
19568 }
19569
19570 SourceLocation ELoc = RefExpr->getExprLoc();
19571 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
19572
19573 if (!SimpleExpr->isLValue()) {
19574 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19575 << 1 << 0 << RefExpr->getSourceRange();
19576 continue;
19577 }
19578
19579 ExprResult Res;
19580 {
19581 Sema::TentativeAnalysisScope Trap(*this);
19582 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
19583 }
19584 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
19585 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
19586 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19587 << 1 << 0 << RefExpr->getSourceRange();
19588 continue;
19589 }
19590 Vars.push_back(SimpleExpr);
19591 }
19592
19593 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
19594 EndLoc, Modifier, Vars);
19595}
19596